【考研】数据结构(更新到循环链表)

news2024/11/17 23:59:32

声明:所有代码都可以运行,可以直接粘贴运行(只有库函数没有声明)

线性表的定义和基本操作

基本操作

  1. 定义
    静态:
#include<stdio.h>
#include<stdlib.h>

#define MaxSize 10

//静态 
typedef struct{
	int data[MaxSize];
	int length;
}SqList;

void InitList(SqList &L)//初始化 
{
	for(int i=0;i<MaxSize;i++){
		L.data[i]=0;
	}
    L.length=0;
}

int main(void)
{
	SqList L;
	InitList(L);
	
	for(int i=0;i<L.length;i++){
		printf("the data %d is %d",i,L.data[i]);
	}
	
	return 0;
}

动态:

#include<stdio.h>
#include<stdlib.h>

#define InitSize 10

typedef struct{
	int *data;
	int MaxSize;//最大容量 
	int length;//当前长度 
}SeqList;

void Init(SeqList &L)
{
	L.data=(int *)malloc(InitSize*sizeof(int));
	L.length=0;
	L.MaxSize=InitSize;
}

int main(void){
	
	return 0;
}
  1. 插入
    静态:
//插入操作,bool用于判断操作是否成功 (处理异常情况) 
bool ListInsert(SqList &L,int i,int e){
	if(i<1 || i>L.length+1) return false;//条件判断 
	if(L.length >= MaxSize) return false;
	
	for(int j=L.length;j>=i;i--){
		L.data[j]=L.data[j-1];
	}
	L.data[i-1]=e;
	L.length++;
}

在这里插入图片描述
动态:


  1. 删除
    静态:
bool ListDelete(SqList &L,int i,int &e){
	if(i<1||i>L.length) return false;
	e=L.data[i-1];
	for(int j=i;j<L.length;j++)
	{
		L.data[j-1]=L.data[j];
	}
	L.length--;
	return true;
}

动态顺序表以及各个操作

#include<stdio.h>
#include<stdlib.h>
#define InitSize 10

typedef struct{
	int *data;
	int MaxSize;
	int length;
}SqList;

void debug(SqList L){
	printf("当前顺序表的数据为length=%d maxsize=%d\n",L.length,L.MaxSize);
}
//初始化
void InitList(SqList &L){
	L.data=(int *)malloc(InitSize*sizeof(int));
	L.length=0;
	L.MaxSize=InitSize;
}
 
//增加动态数组的长度
void IncreaseSize(SqList &L,int len){
	int *p=L.data;
	L.data=(int *)malloc((L.MaxSize+len)*sizeof(int));
	for(int i=0;i<L.length;i++){
		L.data[i]=p[i];//将数据复制到新区域 
	}
    L.MaxSize=L.MaxSize+len;//顺序表最大长度增加len 
	free(p);//释放空间		
} 

//插入操作
bool ListInsert(SqList &L,int i,int e){
	//范围判断 
	if(i<1 || i>L.length+1)
		return false;
	if(L.length>L.MaxSize)
	return false;
	
	for(int j=L.length;j>=i;j--)
	{
		L.data[j]=L.data[j-1];
	}
	L.data[i-1]=e;
	L.length++;
	return true;
} 

删除操作,删除第i个数据并且返回被删除的数据 
bool ListDelete(SqList &L,int i,int &e)
{
	//范围判断
	 if(i<1 || i>L.length+1) return false;
	 else{
	 	//保存删除元素
		 e=L.data[i]; 
	 	for(int j=i;j<L.length;j++)
	 	{
		 L.data[j]=L.data[j+1];
	    }
	    L.length--;
	 } 
	 return true;
 } 

//按位查找
int getElemBybit(SqList L,int i){
	//Check if the line has been crossed
	if(i<1 || i>L.length){
		printf("Cross the border!");
		return 0;
	}
	
	return L.data[i-1];
} 

//按值查找
int getElemByValue(SqList L,int value){
	for(int i=0;i<L.length;i++)
	{
		if(L.data[i] == value)
		{
			return i-1;
		}
	}
	printf("Can`t find the elem!");
	
	return 0;
} 

//打印操作
void print(SqList L){
	for(int i=0;i<L.length;i++)
	{
		printf("%d ",L.data[i]);
	}
	printf("\n");
} 

//测试函数 
int main(void){
	SqList L;debug(L);
	InitList(L);debug(L);
	
	for(int i=0;i<L.MaxSize;i++)
	{
		L.data[i]=i;
	    L.length++;
	}
	IncreaseSize(L,5);debug(L);
	
	print(L);
	if(ListInsert(L,2,5)){
	printf("插入成功,插入后数值");
		print(L);
	}else printf("插入失败");
	
	int e=0;
	if(ListDelete(L,3,e))
	{
		print(L);
		printf("被删除元素为:%d",e);
	}

    int value,position;
	printf("\nPlease input the value and the position:");  
    scanf("%d %d", &value, &position);  
	printf("\nget the emlem by value :the elem position is%d\n",getElemByValue(L,value));
	printf("\nget the emlem by positon:the value is%d\n",getElemBybit(L,position));
	
	return 0;
}

链表基本

链表结构:
单链表:

//定义单链表
typedef struct LNode {
	int data;           // 数据域 
	struct LNode* next; // 指针域 
} LNode, * LinkList;

双链表:

//定义结构
typedef struct DNode{
	int data;//数据域 
	struct DNode *prior,*next;//指针域 
}DNode,*DLinkList;

单链表

操作:

// 初始化一个链表,带头结点
bool InitList(LinkList* L);

// 按照位序插入
bool ListInsert(LinkList* L, int i, int e);

// 指定结点的后插操作
bool InsertNextNode(LNode* p, int e);

// 指定结点的前插操作
bool InsertPriorNode(LNode* p, int e);

// 按位序删除结点
bool ListDelete(LinkList* L, int i, int* e);

// 创建方式 - 头插法创建
LinkList List_HeadInsert(LinkList* L);

//创建方法 - 尾插法创建
LinkList List_TailInsert(LinkList* L);

//指定结点的删除
bool DeleteNode(LNode *p);

//按位查找
LNode *GetElem(LinkList L,int i);

//按值查找
LNode *LocateElem(LinkeList L,int e); 

//求单链表的长度
int length(LinkList L);

//链表逆置
LNode *Inverse(LNode *L); 

// 打印链表
void print(LinkList L); 

操作实现:

// 打印链表
void print(LinkList L) {
	LinkList E = L->next;

	while (E != NULL) {
		printf("%d ", E->data);
		E = E->next;
	}
	printf("\n");
}

// 初始化一个链表,带头结点
bool InitList(LinkList* L) {
	*L = (LNode*)malloc(sizeof(LNode));

	if (*L == NULL) return false;
	(*L)->next = NULL;
	printf("Initialization of the linked list succeeded!\n");
	return true;
}

// 按照位序插入
bool ListInsert(LinkList* L, int i, int e) {
	if (i < 1) return false; // 判断操作合法

	LNode* p = *L;
	int j = 0;
	while (p != NULL && j < i - 1) {
		p = p->next;
		j++;
	}
     
    int choice =0;
    printf("Prior or next?(1/2)");
    scanf("%d",&choice);
    if(choice == 2)
	return InsertNextNode(p, e);
	if(choice == 1)
	return InsertPriorNode(p,e);
	else
	return false;
}

// 指定结点的后插操作 
bool InsertNextNode(LNode* p, int e) {
	if (p == NULL) return false; // 判断合法 

	LNode* s = (LNode*)malloc(sizeof(LNode));
	if (s == NULL) return false; // 内存分配失败 

	s->data = e;
	s->next = p->next;
	p->next = s;

	return true;
}

// 指定结点的前插操作
bool InsertPriorNode(LNode* p, int e) {
	if (p == NULL) return false;

	LNode* s = (LNode*)malloc(sizeof(LNode));
	if (s == NULL) return false;

	s->next = p->next;
	p->next = s;
	s->data = p->data; // 交换数值从而实现前插操作,方法还是后插的方法 
	p->data = e;

	return true;
}

// 按位序删除结点并返回删除数据 
bool ListDelete(LinkList* L, int i, int* e) {
	if (i < 1) return false; // 判断操作合法

	LNode* p = *L;
	int j = 0;

	while (p != NULL && j < i - 1) {
		p = p->next;
		j++;
	} // 定位到删除结点
	if (p == NULL) return false;
	if (p->next == NULL) return false;

	LNode* q = p->next;
	*e = q->data;
	p->next = q->next;
	free(q);

	return true;
}


// 创建方式
// 1. 头插法创建 O(n)
LinkList List_HeadInsert(LinkList* L) {
	*L = (LinkList)malloc(sizeof(LNode)); // 建立头结点
	(*L)->next = NULL;                    // 初始为空链表,这步不能少!

	int x;
	LNode* s;
	printf("input the x:");
	scanf("%d", &x);
	while (x != 9999) {
		s = (LNode*)malloc(sizeof(LNode));
		s->data = x;
		s->next = (*L)->next;
		(*L)->next = s;
		printf("Continue input the x:");
		scanf("%d", &x);
	}
	return *L;
}

//指定结点的删除(重点理解) 
bool DeleteNode(LNode *p){
	if(p == NULL) return false;
	
	LNode *q=p->next;
	p->data=p->next->data;
	p->next=q->next;
	free(q);
	
	return true;
}

//按位查找
LNode *GetElem(LinkList L,int i){
	if(i<1) return false;
	
	LNode *p=L->next;
	int j;
	while(p!=NULL && j<i-1){
		p=p->next;
		j++;
	}
	return p;
}

//按值查找
LNode *LocateElem(LinkList L,int e){
	if(L == NULL) return false;
	
	LNode *p=L->next;
	while(p != NULL && p->data!=e){
		p=p->next;		
	}
	return p;
}

//求单链表的长度
int length(LinkList L){
	int len=0;
	LNode *p=L;
	
	while(p->next!=NULL)
	{
		p=p->next;
		len++;
	}
	
	return len;
} 

//创建方法 - 尾插法创建
//创建方法 - 尾插法创建
LinkList List_TailInsert(LinkList* L){
	int x;
	*L=(LinkList)malloc(sizeof(LNode));
	LNode *s,*r=*L;
	
	printf("输入插入的结点的值:");
	scanf("%d",&x);
	while(x != 9999){
		s=(LNode *)malloc(sizeof(LNode));
		s->data=x;
		r->next=s;
		r=s;
		scanf("%d",&x);
	}
	r->next=NULL;
	
	return *L;
}

//链表逆置(重点理解) 
LNode *Inverse(LNode *L){
	LNode *p,*q;
	p=L->next;
	L->next=NULL;
	
	while(p!=NULL){
		q=p;
		p=p->next;
		q->next=L->next;
		L->next=q;
	}
	
	return L;
}

测试代码

int main(void) {
	LinkList L = NULL;
	LNode *elem = NULL;
	int e=0;
	
	List_HeadInsert(&L);print(L);
	printf("Insert:\n");
	ListInsert(&L,2,3);	print(L);
	ListDelete(&L,3,&e);print(L);
	printf("Deleted elem:%d\n",e);
	printf("Delete the elem by Node\n");
	DeleteNode(L->next->next);print(L);
	printf("Search by position\n");
	elem=GetElem(L,3);printf("the elem is:%d\n",elem->data);
	printf("Inverse the Link\n");
	L=Inverse(L);print(L);
	
	return 0;
}

双链表

操作:

//打印 
void print(DLinkList L);
//链表的初始化 ,
bool InitLinkList(DLinkList *L);
//判空
bool isEmpty(DLinkList L); 
//后插操作,将s插入p之后 
bool InsertNextNode(DNode *p,DNode *s); 
//前插操作
bool InsertPriorNode(DNode *p,DNode *s); 

定义:

bool InitLinkList(DLinkList *L){
	*L = (DNode *)malloc(sizeof(DNode));
	if(L == NULL) return false;
	
	(*L)->next=NULL;
	(*L)->prior=NULL;
	return true; 
}

bool isEmpty(DLinkList L){
	if(L->next==NULL) return true;
	else
 		return false;
}
 
bool InsertNextNode(DNode *p,DNode *s){
	if(p==NULL || s==NULL){
		printf("非法\n");return false;
	}
	
	s->next=p->next;
	s->prior=p;
	p->next=s;
	
	printf("Insert next node success!\n");
	return true;
}

bool InsertPriorNode(DNode *p,DNode *s){
	if(p==NULL || s==NULL || p->prior==NULL){
		printf("非法\n");return false;
	}
	
	s->prior=p->prior;
	s->next=p;
	p->prior=s;
	
	
	printf("Insert prior node success!\n");
	return true;
}

void print(DLinkList L){
	L=L->next;//因为有头结点 
	while(L!=NULL)
	{
		printf("%d ",L->data);
		L=L->next;
	}
}

测试:

//测试 
int main(void){
    
	DLinkList L;
	DNode *node;
	int data,x;
		
	if(InitLinkList(&L)){
		printf("初始化成功!");	
	}
	printf("开始插入(9999停止)\n");
	scanf("%d",&x);
	while(x !=9999){
		node=(DNode *)malloc(sizeof(DNode));
		node->data=x;
		InsertNextNode(L,node);
		scanf(" %d",&x);
	}
	print(L);
  	
	return 0;
}

单循环链表.

//循环链表
#include<stdio.h>
#include<stdlib.h>

//循环单链表 
typedef struct LNode{
	int data;
	struct LNode *next;
}DNode,*LinkList;

//打印
void print(LinkList L); 
//初始化一个循环单链表
bool InitList(LinkList *L); 
//判空
bool isEmpty(LinkList L); 
//判断结点是否为表尾指针
bool ifTail(LinkList L,LNode *p); 
//插入结点
bool InsertNextNode(LNode *p,LNode *q);

int main(void)
{
	LinkList L;
	LNode *node;
	int x;
	if(InitList(&L)) printf("初始化成功!\n");
	
	printf("输入9999结束!\n");
	scanf("%d",&x);
	while(x != 9999){
		node=(LNode *)malloc(sizeof(LNode));
		node->data=x;
		InsertNextNode(L,node);
		scanf(" %d",&x);
	}
	print(L);
	
	
	return 0;
 } 
 
bool InitList(LinkList *L){
	*L=(LNode *)malloc(sizeof(LNode));
	if(*L==NULL) return false;
	
	(*L)->next = *L;
	return true;
}

bool isEmpty(LinkList L){
	if(L->next == L)return true;
	else
		return false;
}

void print(LinkList L){
	LinkList head=L->next;
	
	while(head != L){
		printf("%d ",head->data);
		head=head->next;
	}
}

bool ifTail(LinkList L,LNode *p){
	if(p->next == L)return true;
	else
		return false;
}

bool InsertNextNode(LNode *p,LNode *q){
	if(p==NULL || q==NULL) return false;
	
	q->next=p->next;
	p->next=q;
	return true;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1242176.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【23真题】Top3!最高148分,数二英二!

今天分享的是23年西安交通大学815的信号与系统数字信号处理试题及解析。众所周知&#xff0c;Top3一共有10所&#xff0c;其中就包括了西安交大&#xff01; 本套试卷难度分析&#xff1a;平均分为117-128分&#xff0c;最高分为148分&#xff01;22年西安交大909/815的真题我…

一点DETR学习

DETR: 主要是为了学习query。 主要从两个方面&#xff1a;加偏好和缩短序列长度

rabbit MQ的延迟队列处理模型示例(基于SpringBoot延时插件实现)

rabbitMQ安装插件rabbitmq-delayed-message-exchange 交换机由此type 表示组件安装成功 生产者发送消息时设置延迟值 消息在交换机滞纳至指定延迟后&#xff0c;进入队列&#xff0c;被消费者消费。 组件注解类&#xff1a; package com.esint.configs;import org.springfra…

vue3的单组件的编写(三)【响应式 API 之 toRef 与 toRefs】

响应式 API 之 toRef 与 toRefs 前面讲了 ref 和 reactive 这两种响应式API &#xff0c;为了方便开发者使用&#xff0c;vue3 还出了两个用来 reactive 转换为 ref 的API&#xff0c;分别是 toRef 和 toRefs 。 &#x1f308;什么是toRef 与 toRefs 这两个API看拼写能猜到&…

深度学习之基于Pytorch照片图像转漫画风格网络系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 以下是一个基本的设计介绍&#xff1a; 数据准备&#xff1a;收集足够的真实照片和漫画图像&#xff0c;用于训练模…

SSM整合1

请求参数 (这里的形参数据都是SpringMvc注入的) controller里的方法不是我们来调用的 是由SpringMvc的前端控制器所调用的(前端控制器调用了处理器 由处理器和适配器去调用我们controller里的方法)&#xff0c;controller里的方法叫handler->处理器 SpringMVC的Controller方…

分布式锁之基于redis实现分布式锁(二)

2. 基于redis实现分布式锁 2.1. 基本实现 借助于redis中的命令setnx(key, value)&#xff0c;key不存在就新增&#xff0c;存在就什么都不做。同时有多个客户端发送setnx命令&#xff0c;只有一个客户端可以成功&#xff0c;返回1&#xff08;true&#xff09;&#xff1b;其他…

快速排序演示和代码介绍

快速排序的核心是(以升序为例)&#xff1a;在待排序的数据中指定一个数做为基准数&#xff0c;把所有小于基准数的数据放到基准数的左边&#xff0c;所有大于基准数的数据放在右边&#xff0c;这样的话基准数的位置就确定了&#xff0c;然后在两边的数据中重复上述操作

【好玩的开源项目】Linux系统之部署proxx扫清黑洞小游戏

【好玩的开源项目】Linux系统之部署proxx扫清黑洞小游戏 一、proxx小游戏介绍1.1 proxx小游戏简介1.2 开源地址 二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、检查本地环境3.1 检查本地操作系统版本3.2 检查系统内核版本 四、部署Node.js环境4.1 下载Node.js安装包4.…

使用docker命令_进入容器_登录mysql服务_并执行sql语句---Docker工作笔记005

今天就用到了,不得不说用docker用到的还是少,记录一下,常用的也就这些吧. 首先执行: docker ps [root@localhost dataease-1.18.9]# docker ps CONTAINER ID IMAGE COMMAND CREATED …

itext - PDF模板套打

项目需求&#xff1a;获取列表数据之后直接将数据生成一个pdf。因此需要使用到 itext 对pdf进行直接操作。 环境配置 需要为pdf添加文字域&#xff0c;因此需要安装Adobe Acrobat 准备一个空的PDF文件&#xff0c;如果有现成的模板更好 依赖配置&#xff0c;我们使用itext的7版…

设计模式-16-Spring源码中的设计模式

1-Spring之观察者模式 Java、Google Guava都提供了观察者模式的实现框架。Java提供的框架比较简单&#xff0c;只包含java.util.Observable和java.util.Observer两个类。Google Guava提供的框架功能比较完善和强大&#xff1a;通过EventBus事件总线来实现观察者模式。实际上&am…

mac电脑文件比较工具 UltraCompare 中文for mac

UltraCompare是一款功能强大的文件和文件夹比较工具&#xff0c;用于比较和合并文本、二进制和文件夹。它提供了丰富的功能和直观的界面&#xff0c;使用户能够轻松地比较和同步文件内容&#xff0c;查找差异并进行合并操作。 以下是UltraCompare软件的一些主要特点和功能&…

并行与分布式计算 第9章 算法设计

文章目录 并行与分布式计算 第9章 算法设计9.1 设计过程9.1.1 PCAM设计过程9.1.2 划分9.1.3 通信9.1.4 组合9.1.5 映射 8.2 设计方法8.2.1 划分技术9.2.2 分治9.2.3 平衡树技术9.2.4倍增技术9.2.5 流水线技术9.2.6 破对称技术 并行与分布式计算 第9章 算法设计 9.1 设计过程 …

【LeetCode:1410. HTML 实体解析器 | 模拟+哈希表+字符串+库函数】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

2024年荆州中级工程师职称申报时间是什么时候?

甘建二十年耕耘职称。 2024年荆州中级工程师职称开始准备了&#xff0c;关于荆门中级职称具体申报时间&#xff0c;甘建二告诉你。 ​2024年荆州中级工程师职称申报时间&#xff1a; 1.水平能力测试报名3月份 2.水平能力测试考试4月份3.职称申报9月份&#xff0c;采取的是网上申…

多个视频怎么生成一个二维码?二维码看视频的制作方法

二维码能放入多个视频吗&#xff1f;现在用二维码看视频是很流行的一种方式&#xff0c;不仅符合现在人的行为习惯&#xff0c;而且还不需要占用自身的容量空间&#xff0c;能够即时的获取视频内容。那么当有多个视频需要展示&#xff0c;但是想要放到一个二维码中&#xff0c;…

【开源】基于Vue.js的天然气工程运维系统的设计和实现

项目编号&#xff1a; S 022 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S022&#xff0c;文末获取源码。} 项目编号&#xff1a;S022&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统角色分类2.2 核心功能2.2.1 流程…

界面组件Telerik UI for WinForms中文教程 - 创建明暗模式的桌面应用

黑暗模式现在在很多应用程序中都挺常见的&#xff0c;但如何在桌面应用程序中实现它呢&#xff1f;这很简单&#xff0c;本文将为大家介绍如何使用一个类和命令行调用来实现&#xff01; Telerik UI for WinForms拥有适用Windows Forms的110多个令人惊叹的UI控件。所有的UI fo…

vue中列表渲染

列表渲染 实际开发中&#xff0c;使用每条数据的唯一标识作为key,也就是对于数组列表&#xff0c;对象中的属性如&#xff1a;id、手机号、身份证号、学号等唯一值&#xff0c;对象列表同理 只要不对列表的逆序添加&#xff0c;逆序删除等破坏顺序的操作&#xff0c;仅用于渲染…