刘佳瑜*,王越 *, 黄扬* , 张钊*
(淮北师范大学计算机科学与技术学院,安徽 淮北)
*These authors contributed to the work equllly and should be regarded as co-first authors.
🌞欢迎来到数据结构的世界
🌈博客主页:卿云阁💌欢迎关注🎉点赞👍收藏⭐️留言📝
🌟本文由卿云阁原创!
🙏作者水平很有限,如果发现错误,请留言轰炸哦!万分感谢!
目录
🍈 线性表的定义
🍉顺序表
存储结构
定义和初始化
静态分配
- L代表是一个线性表,包含两个元素,一个是data数组,一个是当前数组的长度。
- 初始化时,将data数组中的元素是0,线性表的长度是0。
#include<stdio.h> #define MaxSize 5 typedef struct { int data[MaxSize]; int length; }SqList; void InitList(SqList &L) { int i; for(i=0;i<MaxSize;i++) L.data[i]=0; L.length=0; } int main() { SqList L; InitList(L); return 0; }
动态分配
- InitSize代表顺序表的初始长度
- MaxSize代表顺序表当前的最大容量
- length代表顺序表的当前的长度
- 初始化时,data,MaxSize=InitSize,length=0
#include<stdio.h> #include<stdlib.h> #define InitSize 5 typedef struct { int *data; int MaxSize; int length; }SqList; void InitList(SqList &L) { L.data=(int *)malloc(sizeof(int)*InitSize); L.MaxSize=InitSize; L.length=0; } int main() { SqList L; InitList(L); return 0; }
增加数组空间的长度
- 定义指针变量p保存当前的地址
- 给data重新分配增加后的内存空间
- 把之前空间的值,复制到当前的地址空间
- 顺序表的最大容量增加
- 释放原来的地址空间
#include<stdio.h> #include<stdlib.h> #define INITSIZE 10 typedef int DataType; typedef struct{ DataType *data; int length; int maxsize; }SqList; //定义顺序表类型 void InitSqList(SqList &L,int initsize) { printf("%d\n",initsize); L.data=(DataType *)malloc(sizeof(DataType )*initsize); L.length=0; L.maxsize=initsize; } //增加动态数组的长度 void IncreaseSize(SqList &L,int len) { int *p=L.data; int i; L.data=(DataType *)malloc(sizeof(DataType )*(INITSIZE+len)); for(i=0;i<L.length;i++) L.data[i]=p[i]; L.maxsize+=len; free(p); } int main() { SqList L; InitSqList(L,INITSIZE); IncreaseSize(L,5); return 0; }
插入
比如在第三个元素插入元素2
- 把第length个元素,到第2个元素向后移动
- 插入2
#include<stdio.h> #define MAXSIZE 5 //MAXSIZE是根据实际问题定义的足够大的整数常量 typedef int DataType; typedef struct{ DataType data[MAXSIZE]; int length; }SqList; //定义顺序表类型 void InitSqList(SqList &L) { L.length=3; L.data[0]=0; L.data[1]=1; L.data[2]=3; } bool InsertSqList(SqList &L,int i,DataType x) { int j; if(L.length>=MAXSIZE) { printf("\n顺序表是满的,无法插入元素!"); return false; } if(i<1||i>L.length+1) { printf("\n指定的插入位置不存在!"); return false; } for(j=L.length;j>=i;j--) L.data[j]=L.data[j-1]; L.data[i-1]=x; L.length++; return true; } int main() { SqList L; InitSqList(L); InsertSqList(L,3,2); return 0; }
删除
比如在删除第3个元素,并带回删除的值
- 删除第3个元素
- 把第3个元素,到第lengh个元素向后移动
#include<stdio.h> #include<stdlib.h> #define MAXSIZE 5 //MAXSIZE是根据实际问题定义的足够大的整数常量 typedef int DataType; typedef struct{ DataType data[MAXSIZE]; int length; }SqList; //定义顺序表类型 void InitSqList(SqList &L) { L.length=4; L.data[0]=0; L.data[1]=1; L.data[2]=4; L.data[3]=2; } bool DeleteSqList(SqList &L,int i,int &e) { int j; if(L.length==0) { printf("\n顺序表是空的,无法删除元素!"); return false; } if(i<1||i>L.length) { printf("\n指定的删除位置不存在!"); return false; } e=L.data[i-1]; for(j=i;j< L.length;j++) L.data[j-1]=L.data[j]; L.length--; return true; } int main() { SqList L; InitSqList(L); int x=3; int e; DeleteSqList(L,x,e); return 0; }
查找
按位查找
#include<stdio.h> #include<stdlib.h> #define MAXSIZE 5 //MAXSIZE是根据实际问题定义的足够大的整数常量 typedef int DataType; typedef struct{ DataType data[MAXSIZE]; int length; }SqList; //定义顺序表类型 void InitSqList(SqList &L) { L.length=4; L.data[0]=0; L.data[1]=1; L.data[2]=4; L.data[3]=2; } DataType GetElem(SqList L,int i) { return L.data[i-1]; } int main() { SqList L; int a;//接受查找到的元素 InitSqList(L); a=GetElem(L,3); printf("this:%d",a); return 0; }
按值查找
#include<stdio.h> #define MAXSIZE 5 //MAXSIZE是根据实际问题定义的足够大的整数常量 typedef int DataType; typedef struct{ DataType data[MAXSIZE]; int length; }SqList; //定义顺序表类型 void InitSqList(SqList L) { L.length=4; L.data[0]=0; L.data[1]=1; L.data[2]=4; L.data[3]=2; } int LocationSqList(SqList L, DataType x) { int i; for (i=0; i<L.length; i++) if (L.data[i] == x) //查找成功,返回元素位置i return i+1; if (i == L.length) //查找失败,返回-1 return -1; } int main() { SqList L; InitSqList(L); LocationSqList(L, 4); return 0; }
🍊单链表
节点的结构
- 一个节点包含两个信息
- 一个是存放数据
- 一个存放指向下一个节点的指针
不带头结点的单链表第一个节点开始存储数据#include<stdio.h> #define MAXSIZE 5 typedef int DataType; typedef struct Node { DataType data; struct Node *next; }LNode , *LinkList; bool InitList(LinkList &L) { L=NULL; return true; } bool Empty(LinkList L) { return (L==NULL); } int main() { LinkList L; InitList(L); return 0; }
带头结点的单链表新建一个头结点指向第一个节点#include<stdio.h> #include<stdlib.h> #define MAXSIZE 5 typedef int DataType; typedef struct Node { DataType data; struct Node *next; }LNode , *LinkList; bool InitList(LinkList &L) { L=(LNode *)malloc(sizeof(LNode)); if (L==NULL) return false; L->next=NULL; return true; } bool Empty(LinkList L) { if (L->next==NULL) return true; else return false; } int main() { LinkList L; InitList(L); return 0; }
建立单链表
头插法
#define flag -1 #include<stdio.h> #include<stdlib.h> #define MAXSIZE 5 typedef int DataType; typedef struct Node { DataType data; struct Node *next; }LNode , *LinkList; bool InitList(LinkList &L) { L=(LNode *)malloc(sizeof(LNode)); if (L==NULL) return false; L->next=NULL; return true; } bool Empty(LinkList L) { if (L->next==NULL) return true; else return false; } int CreatLinkList(LinkList &L) { LNode *s; DataType x; int count=0;//记录输入的节点的个数 printf("请输入第一个节点的值:\n"); scanf("%d",&x); while(x!=flag) { s=(LinkList)malloc(sizeof(LNode)); s->data=x; s->next=L->next; L->next=s; count++; printf("请输入下一个节点的值:\n"); scanf("%d",&x); } return count; } void printLinkList(LinkList &L,int count) { int i; LNode *s=L->next; for(i=0;i<count;i++) { printf("第%d个节点的值:%d\n",(i+1),(s->data)); s=s->next; } } int main() { printf("使用头插法建立单链表\n"); int count; LinkList L; InitList(L); count=CreatLinkList(L); printLinkList(L,count); return 0; }
尾插法
#define flag -1 #include<stdio.h> #include<stdlib.h> #define MAXSIZE 5 typedef int DataType; typedef struct Node { DataType data; struct Node *next; }LNode , *LinkList; //初始化操作 bool InitList(LinkList &L) { L=(LNode *)malloc(sizeof(LNode)); if (L==NULL) return false; L->next=NULL; return true; } //判空操作 bool Empty(LinkList L) { if (L->next==NULL) return true; else return false; } //头插法建立单链表 int CreatLinkList(LinkList &L) { LNode *s; //定义一个节点s DataType x; //定义一个数表示插入的元素 int count=0; //记录输入的节点的个数 printf("请输入第一个节点的值:\n"); scanf("%d",&x); while(x!=flag) { s=(LinkList)malloc(sizeof(LNode)); s->data=x; s->next=L->next; L->next=s; count++; printf("请输入下一个节点的值:\n"); scanf("%d",&x); } return count; } //打印链表 void printLinkList(LinkList &L,int count) { int i; LNode *s=L->next; for(i=0;i<count;i++) { printf("第%d个节点的值:%d\n",(i+1),(s->data)); s=s->next; } } int main() { printf("使用头插法建立单链表\n"); int count; LinkList L; InitList(L); count=CreatLinkList(L); printLinkList(L,count); return 0; }
查找运算
按位查找&按值查找
#define flag -1 #include<stdio.h> #include<stdlib.h> #define MAXSIZE 5 typedef int DataType; typedef struct Node { DataType data; struct Node *next; }LNode , *LinkList; bool InitList(LinkList &L) { L=(LNode *)malloc(sizeof(LNode)); if (L==NULL) return false; L->next=NULL; return true; } bool Empty(LinkList L) { if (L->next==NULL) return true; else return false; } int CreatLinkList(LinkList &L) { LNode *s,*r; DataType x; int count=0;//记录输入的节点的个数 r=L; printf("请输入第一个节点的值:\n"); scanf("%d",&x); while(x!=flag) { s=(LinkList)malloc(sizeof(LNode)); s->data=x; r->next=s; r=s; count++; printf("请输入下一个节点的值:\n"); scanf("%d",&x); } r->next=NULL; return count; } void printLinkList(LinkList &L,int count) { int i; LNode *s=L->next; for(i=0;i<count;i++) { printf("第%d个节点的值:%d\n",(i+1),(s->data)); s=s->next; } } LNode *GetLinkList(LinkList L,int i) { LinkList p=L; int j=0;//表示当前查找的位置 while(p->next!=NULL&&j<i) { p=p->next; j++; } return p; } LNode *LocationLinkList(LinkList L,DataType x) { LinkList p=L->next; while(p->next!=NULL&&p->data!=x) { p=p->next; } return p; } int main() { printf("使用尾插法建立单链表\n"); int count; LNode *p1,*p2;//接受查找的结果 LinkList L; InitList(L); count=CreatLinkList(L); printf("建立单链表如下\n"); printLinkList(L,count); printf("查找第3个元素的值:\n"); p1=GetLinkList(L,3); printf("查找第3个元素的值:%d\n",p1->data); printf("4在链表中的地址:\n"); p2=LocationLinkList(L,4); printf("4在链表中的地址%d\n",p2 ); return 0; }
插入运算
#define flag -1 #include<stdio.h> #include<stdlib.h> #define MAXSIZE 5 typedef int DataType; typedef struct Node { DataType data; struct Node *next; }LNode , *LinkList; bool InitList(LinkList &L) { L=(LNode *)malloc(sizeof(LNode)); if (L==NULL) return false; L->next=NULL; return true; } bool Empty(LinkList L) { if (L->next==NULL) return true; else return false; } int CreatLinkList(LinkList &L) { LNode *s,*r; DataType x; int count=0;//记录输入的节点的个数 r=L; printf("请输入第一个节点的值:\n"); scanf("%d",&x); while(x!=flag) { s=(LinkList)malloc(sizeof(LNode)); s->data=x; r->next=s; r=s; count++; printf("请输入下一个节点的值:\n"); scanf("%d",&x); } r->next=NULL; return count; } void printLinkList(LinkList &L,int count) { int i; LNode *s=L->next; for(i=0;i<count;i++) { printf("第%d个节点的值:%d\n",(i+1),(s->data)); s=s->next; } } LNode *GetLinkList(LinkList L,int i) { LinkList p=L; int j=0;//表示当前查找的位置 while(p!=NULL&&j<i) { p=p->next; j++; } return p; } LNode *LocationLinkList(LinkList L,DataType x) { LinkList p=L->next; while(p->next!=NULL&&p->data!=x) { p=p->next; } return p; } void InsertLinkList(LinkList L,int i,DataType x) { LNode *p,*s; p=GetLinkList(L,i-1); if (p==NULL) { printf("插入的位置不合法:\n"); exit(1); } else { s=(LNode *) malloc(sizeof(LNode)); s->data=x; s->next=p->next; p->next=s; } } int main() { printf("使用尾插法建立单链表\n"); int count; LNode *p1,*p2;//接受查找的结果 LinkList L; InitList(L); count=CreatLinkList(L); printf("建立单链表如下\n"); printLinkList(L,count); InsertLinkList(L,3,2); printf("插入2后的单链表如下:\n"); printLinkList(L,count+1); return 0; }
删除运算
#define flag -1 #include<stdio.h> #include<stdlib.h> #define MAXSIZE 5 typedef int DataType; typedef struct Node { DataType data; struct Node *next; }LNode , *LinkList; bool InitList(LinkList &L) { L=(LNode *)malloc(sizeof(LNode)); if (L==NULL) return false; L->next=NULL; return true; } bool Empty(LinkList L) { if (L->next==NULL) return true; else return false; } int CreatLinkList(LinkList &L) { LNode *s,*r; DataType x; int count=0;//记录输入的节点的个数 r=L; printf("请输入第一个节点的值:\n"); scanf("%d",&x); while(x!=flag) { s=(LinkList)malloc(sizeof(LNode)); s->data=x; r->next=s; r=s; count++; printf("请输入下一个节点的值:\n"); scanf("%d",&x); } r->next=NULL; return count; } void printLinkList(LinkList &L,int count) { int i; LNode *s=L->next; for(i=0;i<count;i++) { printf("第%d个节点的值:%d\n",(i+1),(s->data)); s=s->next; } } LNode *GetLinkList(LinkList L,int i) { LinkList p=L; int j=0;//表示当前查找的位置 while(p!=NULL&&j<i) { p=p->next; j++; } return p; } LNode *LocationLinkList(LinkList L,DataType x) { LinkList p=L->next; while(p!=NULL&&p->data!=x) { p=p->next; } return p; } void InsertLinkList(LinkList L,int i,DataType x) { LNode *p,*s; p=GetLinkList(L,i-1); if (p==NULL) { printf("插入的位置不合法:\n"); exit(1); } else { s=(LNode *) malloc(sizeof(LNode)); s->data=x; s->next=p->next; p->next=s; } } void DeleteLinkList(LinkList L,int i) { LNode *p,*q; p=GetLinkList(L,i-1); if (p==NULL) { printf("删除的位置不合法:\n"); exit(1); } else { if(p->next==NULL) { printf("删除的位置不合法:\n"); exit(1); } else { q=p->next; p->next=p->next->next; free(q); } } } int main() { printf("使用尾插法建立单链表\n"); int count; LNode *p1,*p2;//接受查找的结果 LinkList L; InitList(L); count=CreatLinkList(L); printf("建立单链表如下\n"); printLinkList(L,count); InsertLinkList(L,3,2); printf("删除第3个节点的单链表如下:\n"); DeleteLinkList(L,3); printLinkList(L,count-1); return 0; }
求表长运算
#define flag -1 #include<stdio.h> #include<stdlib.h> #define MAXSIZE 5 typedef int DataType; typedef struct Node { DataType data; struct Node *next; }LNode , *LinkList; bool InitList(LinkList &L) { L=(LNode *)malloc(sizeof(LNode)); if (L==NULL) return false; L->next=NULL; return true; } bool Empty(LinkList L) { if (L->next==NULL) return true; else return false; } int CreatLinkList(LinkList &L) { LNode *s,*r; DataType x; int count=0;//记录输入的节点的个数 r=L; printf("请输入第一个节点的值:\n"); scanf("%d",&x); while(x!=flag) { s=(LinkList)malloc(sizeof(LNode)); s->data=x; r->next=s; r=s; count++; printf("请输入下一个节点的值:\n"); scanf("%d",&x); } r->next=NULL; return count; } void printLinkList(LinkList &L,int count) { int i; LNode *s=L->next; for(i=0;i<count;i++) { printf("第%d个节点的值:%d\n",(i+1),(s->data)); s=s->next; } } LNode *GetLinkList(LinkList L,int i) { LinkList p=L; int j=0;//表示当前查找的位置 while(p!=NULL&&j<i) { p=p->next; j++; } return p; } LNode *LocationLinkList(LinkList L,DataType x) { LinkList p=L->next; while(p!=NULL&&p->data!=x) { p=p->next; } return p; } int LengthLinkList(LinkList L) { int len=0; LNode *p=L; while(p->next) { len++; p=p->next; } return len; } int main() { printf("使用尾插法建立单链表\n"); int count; int length; LNode *p1,*p2;//接受查找的结果 LinkList L; InitList(L); count=CreatLinkList(L); printf("建立单链表如下\n"); printLinkList(L,count); length=LengthLinkList(L); printf("单链表的长度是%d\n",length); return 0; }
🍋双向链表
一个节点的信息包括两个部分
- 第一个是数据部分data
- 第二个是指针(包括指向前一个节点的指针prior和下一个节点的信息next)
初始化的时候(带头节点)
- 第一个是申请一个节点,L指向这个节点
- 第二个是指针(L->prior=NULL和L->next=NULL)
#define flag -1 #include<stdio.h> #include<stdlib.h> #include<stdbool.h> #define MAXSIZE 5 typedef int ElemType; //定义节点信息 typedef struct DNode { ElemType data; struct Node *next,*prior; }DNode , *DLinkList; //初始化 bool InitList(DLinkList &L) { L=(DNode *)malloc(sizeof(DNode)); if(L==NULL) return false; L->prior=NULL; L->next=NULL; return true; } int main() { DLinkList L; InitList(L); return 0; }
插入运算(带头节点)
- 第一个是申请一个节点,L指向这个节点
- 第二个是指针(s->next=p->next,s->prior=p->next,p->next->prior=s,p->next=s)
//在p节点后面插入S 节点 bool InsertNextDNode(DNode *p,DNode *s) { if(p==NULL||s==NULL) return false; s->next=p->next; if(p->next!=NULL) p->next->prior=s; s->prior=p; p->next=s; }
删除运算(带头节点)
- 第一个是申请一个节点,L指向这个节点
- 第二个是指针(s->next=p->next,s->prior=p->next,p->next->prior=s,p->next=s)
//删除p的后继节点 bool DeleteNextDNode(DNode *p) { if(p==NULL) return false; DNode *q=p->next; if(q=NULL) return false; p->next=q->next; if(q->next!=NULL) q->next->prior=p; free(p); return true; } //销毁表 void DestoryList(DLinklist &L) { while(L->next!=NUll) DeleteNextDNode(L); free(L); L=NULL; }
🥥循环链表
#define flag -1 #include<stdio.h> #include<stdlib.h> #define MAXSIZE 5 //循环单链表 typedef int ElemType; typedef struct Node { ElemType data; struct Node *next; }LNode , *LinkList; //初始换单链表 bool InitList(LinkList &L) { L=(LNode *)malloc(sizeof(LNode)); if (L==NULL) return false; L->next=L; return true; } //判断是否为空 bool Empty(linkList L) { if(L->next==L) return true; else return false; } //判断节点p是否是表尾节点 bool isTail(LinkList L,LNode *p) { if (p->next==L) return true; else return false; }
#define flag -1 #include<stdio.h> #include<stdlib.h> #define MAXSIZE 5 //循环双链表 typedef int ElemType; typedef struct DNode { ElemType data; struct DNode *next,*prior; }DNode , *DLinkList; //初始换双链表 bool InitList(DLinkList &L) { L=(DNode *)malloc(sizeof(DNode)); if (L==NULL) return false; L->next=L; L->prior=L; return true; } //判断是否为空 bool Empty(DLinkList L) { if(L->next==L) return true; else return false; } //判断节点p是否是表尾节点 bool isTail(DLinkList L,DNode *p) { if (p->next==L) return true; else return false; }
🍇静态链表
Institutional Review Board Statement: Not applicable.
Informed Consent Statement: Not applicable.
Data Availability Statement: Not applicable.
Author Contributions:All authors participated in the assisting performance study and approved the paper.
Conflicts of Interest: The authors declare no conflict of interest