🌞欢迎来到图解数据结构的世界
🌈博客主页:卿云阁💌欢迎关注🎉点赞👍收藏⭐️留言📝
🌟本文由卿云阁原创!
📆首发时间:🌹2024年7月15日🌹
✉️希望可以和大家一起完成进阶之路!
🙏作者水平很有限,如果发现错误,请留言轰炸哦!万分感谢!
目录
线性表的定义和基本操作
顺序表的定义和基本操作
顺序表的定义
顺序表的实现
静态分配
- 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;
}
插入运算(带头节点)
//在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;
}
删除运算(带头节点)
//删除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;
}
静态链表
#define MaxSize 10
typedef struct
{
ElemType data;
int next;
}SLinkList[MaxSize];