一、线性表的概念
定义:线性表是n 个类型相同数据元素的有限序列
线性表的逻辑特性:
1、有限性
2、相同性(同一表中的元素类型相同)
3、相继性
二、线性表的顺序存储
基于博主自己的理解,线性表的顺序存储类似于基本数据类型中的数组,为静态的存储空间。
不可以在除初始化外的地方对顺序表进行扩大。若由于数据过多,导致了原有的数据存储空间不足,则解决方法是申请一个2倍于当前顺序表的空间。将原有的数据复制过去。
顺序表的基本操作
- 初始化顺序表——InitList(Sqlist*L)
- 创造顺序表——CreateList(Sqlist*L)
- 定位数据的位置——Findelem(Sqlist*L)
- 查找位置的数据——Position(Sqlist*L)
- 删除数据——Delete(Sqlist*L)
- 摧毁顺序表——DestroyList(Sqlist*L)
- 清空顺序表——Clearlist(Sqlist*L)
- 判断顺序表是否为空——ListEmpty(Sqlist*L)
- 得到顺序表的表长——ListLength(Sqlist*L)
- 表的插入—— ListInsert(Sqlist*L)
- 表的遍历——ListTraverse(Sqlist*L)
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
typedef struct
{
int data[MAXSIZE];//存放顺序表元素数组
int length;//存放顺序表的长度
}Sqlist;
void InitList(Sqlist*L)
{
L->length=0;
}
void CreateList(Sqlist*L)
{
int n,i,j;
printf("需要创建的元素的个数:");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("请输入第%d个数据:\t",i+1);
scanf("%d",&L->data[i]);
L->length++;
}
printf("顺序表中的数据为:");
for(j=0;j<n;j++)
{
printf("%d\t",L->data[j]);
}
printf("\n顺序表的长度为:%d\n",L->length);
}
void Findelem(Sqlist*L)
{
int i,e;
printf("请输入你要查找的数据:");
scanf("%d",&e);
for(i=0;i>=0&&i<L->length;i++)
{
if(e==L->data[i])
printf("该元素在线性表的第%d个,为%d\n",i+1,L->data[i]);
}
if(i==L->length+1)
{
printf("线性表中无此元素\n");
}
}
void Position(Sqlist*L)
{
int p;
printf("请输入你要查找的位置:\t");
scanf("%d",&p);
if(p-1<=0||p-1>=L->length||p-1>=MAXSIZE)
{
printf("您输入的数据有错误!");
return 0;
}
printf("您所要找的位置元素为%d\n",L->data[p-1]);
}
void Delete(Sqlist*L)
{
int i,j,p;
printf("请输入你要删除的元素位数:");
scanf("%d",&p);
if(p-1<=0||p-1>=L->length||p-1>=MAXSIZE)
{
printf("您输入的数据有错误!");
return 0;
}
else
{
for(i=p-1;i<L->length;i++)
{
L->data[i]=L->data[i+1];
}
L->length--;
printf("删除后所得的数据为:\n");
for(j=0;j<L->length;j++)
{
printf("%d\t",L->data[j]);
}
}
}
void DestroyList(Sqlist*L)
{
free(L);
// L->length=0;
}
void Clearlist(Sqlist*L)
{
int i;
for(i=0;i<L->length;i++);
{
L->data[i]=0;
}
L->length=0;
}
void ListEmpty(Sqlist*L)
{
if(L->length==0)
return 0;
else
return 1;
}
void ListLength(Sqlist*L)
{
int i=0,n=0;
while(L->data[i]==0)
{
n++;
}
printf("顺序表的长度为%d\t%d",n,L->length);
}
void ListInsert(Sqlist*L)
{
int i,j,p,e;
printf("请输入你要插入的元素数据:");
scanf("%d",&e);
printf("请输入你要插入的元素位序:");
scanf("%d",&p);
if(p-1<0||p-1>L->length||p-1>=MAXSIZE)
{
printf("您输入的数据有错误!");
return 0;
}
else
{
for(i=p-1;i<L->length+1;i++)
{
L->data[i+1]=L->data[i];
}
L->data[p-1]=e;
L->length++;
printf("插入后所得的数据为:\n");
for(j=0;j<L->length;j++)
{
printf("%d\t",L->data[j]);
}
}
}
void ListTraverse(Sqlist*L)
{
int i;
for(i=0;i<L->length;i++)
{
printf("%d\t",L->data[i]);
}
}
int main()
{
int a;
char b;
Sqlist L;
InitList(&L);
CreateList(&L);
system("pause");
printf("which function ");
do{
printf("Which function you want to realize:\n");
printf("1. 查找某个元素在顺序表中第一次出现的位置\n");
printf("2. 显示查找位置的数据\n");
printf("3. 删除顺序表中你想删除的元素位置\n");
printf("4. 销毁链表\n");
printf("5. 清除链表\n");
printf("6. 判断链表是否为空\n");
printf("7. 计算链表长度\n");
printf("8. 插入数据\n");
printf("9. 打印数据\n");
printf("0.exit\n");
printf("Which function :");
scanf("%d",&a);/*指定功能*/
getchar();
switch(a)/*选择功能*/
{
case 1:
Findelem(&L);
break;
case 2:
Position(&L);
break;
case 3:
Delete(&L);
break;
case 4:
DestroyList(&L);
break;
case 5:
Clearlist(&L);
break;
case 6:
ListEmpty(&L);
break;
case 7:
ListLength(&L);
break;
case 8:
ListInsert(&L);
break;
case 9:
ListTraverse(&L);
break;
case 0:
exit(0);
}
printf("Do you want to continue?\n");
// getchar()
scanf(" %c",&b);
}while(b=='y'||b=='Y');
return 0;
}
三、线性表的链式存储
1.最常见的单向链表
#include<stdio.h>
#include<stdlib.h>
typedef struct Lnode //定义链表
{
int data;
struct Lnode*next;
}Lnode,*node;
node CreateList();//构造链表头
int Isempty(node Lhead);//判断链表是否为空
void Traverse(node Lhead);//遍历链表
int LengthList(node Lhead);//求表长
node LocateList(int p,node Lhead);//寻找到位置
node InsertList(node Lhead);//插入数据
node DeleteList(node Lhead);//删除数据
int main()
{
int a=0,b=0,l=0;
char c;
node Lhead=NULL;
Lhead=CreateList();
do{
InsertList(Lhead);
printf("Do you want to add again?\n");
scanf(" %c",&c);
}while(c=='y'||c=='Y');
a=Isempty(Lhead);
if(a)//判断链表是否为空
printf("List isn't NULL!\n");
else
printf("List is NULL\n");
do{
printf("which function you want to choose?\n1.Travel list\n2.Lengthlist\n3.Insert\n4.Delete\n");
scanf(" %d",&b);
switch(b)
{
case 1:
Traverse(Lhead);
break;
case 2:
l=LengthList(Lhead);
printf("List's length is %d\n",l);
break;
case 3:
InsertList(Lhead);
break;
case 4:
DeleteList(Lhead);
break;
default:
exit(0);
}
}while(b!=5);
return 0;
}
node CreateList()
{
node Lhead;
Lhead=(node)malloc(sizeof(Lnode));
if(!Lhead==NULL)
{
Lhead->next=NULL;
return Lhead;
}
else
printf("Fail to apply space!");
}
int Isempty(node Lhead)
{
if(Lhead->next==NULL)
return 0;
else
return 1;
}
void Traverse(node Lhead)
{
node L;
L=Lhead;
if(!Isempty(L))
{
printf("List is NULL!");
}
else
{
while(L->next!=NULL)
{
L=L->next;
printf(" %d",L->data);
}
}
}
int LengthList(node Lhead)
{
int i=0;
node L=Lhead;
while(L->next!=NULL)
{
i++;
L=L->next;
}
return i;
}
node LocateList(int p,node Lhead)
{
node L;
L=Lhead;
while(p-1>0&&L!=NULL)
{
p--;
L=L->next;
}
if(p==1)
return L;
else
{
printf("Position is not exist!");
return NULL;
}
}
node InsertList(node Lhead)
{
int e,p;
node L1=Lhead,LInsert=NULL;
T:
L1=Lhead;
LInsert=CreateList();
printf("Please input where you want to insert: ");
scanf(" %d",&p);
printf("Please input your elem: ");
scanf(" %d",&e);
LInsert->data=e;
L1=LocateList(p,L1);
if(L1==NULL)
{
printf("input wrong!\n");
goto T;
}
else
{
LInsert->next=L1->next;
L1->next=LInsert;
}
}
node DeleteList(node Lhead)
{
int p;
node L1=Lhead,L2=Lhead;
T:
L1=Lhead;
printf("Please input where you want to delete.");
scanf(" %d",&p);
L1=LocateList(p,L1);
if(L1==NULL)
goto T;
else
{
while(L1->next!=L2)
{
L2=L2->next;
}
L1->next=L2->next;
free(L2);
L2=NULL;
}
}
2.双向链表
#include<stdio.h>
#include<stdlib.h>
typedef struct Lnode //定义链表
{
int data;
struct Lnode*next;
struct Lnode*prior;
}Lnode,*node;
node Create();//申请空间
node CreateList();//构造链表
int Isempty(node Lhead);//判断链表是否为空
void Traverse(node Lhead);//遍历链表
int LengthList(node Lhead);//求表长
node LocateList(int p,node Lhead);//寻找到位置
node InsertList(node Lhead);//插入数据
node DeleteList(node Lhead);//删除数据
int main()
{
int a=0,b=0,l=0;
char c;
node Lhead=NULL;
Lhead=CreateList();
a=Isempty(Lhead);
if(a)//判断链表是否为空
printf("List isn't NULL!\n");
else
printf("List is NULL\n");
do{
printf("which function you want to choose?\n1.Travel list\n2.Lengthlist\n3.Insert\n4.Delete\n");
scanf(" %d",&b);
switch(b)
{
case 1:
Traverse(Lhead);
break;
case 2:
l=LengthList(Lhead);
printf("List's length is %d\n",l);
break;
case 3:
InsertList(Lhead);
break;
case 4:
DeleteList(Lhead);
break;
default:
exit(0);
}
}while(b!=5);
return 0;
}
node Create()
{
node Lhead;
Lhead=(node)malloc(sizeof(Lnode));
if(!Lhead==NULL)
{
Lhead->next=NULL;
return Lhead;
}
else
{
printf("Fail to apply space!");
return NULL;
}
}
node CreateList()
{
node Lhead;
node Lnext;
node Lprior;
int n,e,i=0;
Lhead=(node)malloc(sizeof(Lnode));
if(!Lhead==NULL)
Lhead->next=NULL;
else
printf("Fail to apply space!");
Lprior=Lhead;
printf("How long double list you want: ");
scanf("%d",&n);
while(i<n)//循环判断是否输入完整
{
i++;
printf("please input the number %d elem: ",i);
scanf("%d",&e);
Lnext=(node)malloc(sizeof(Lnode));
if(!Lnext==NULL)
Lnext->next=NULL;
else
printf("Fail to apply space!");
Lnext->data=e;//节点地的数据输入
Lprior->next=Lnext;//尾节点后指针指向新节点
Lnext->prior=Lprior;//新节点头指针指向尾节点
Lprior=Lnext;//上一个尾节点成为新的尾节点
}
return Lhead;
}
int Isempty(node Lhead)
{
if(Lhead->next==NULL)
return 0;
else
return 1;
}
void Traverse(node Lhead)
{
node L;
L=Lhead;
if(!Isempty(L))
{
printf("List is NULL!");
}
else
{
while(L->next!=NULL)
{
L=L->next;
printf(" %d",L->data);
}
printf("\n");
}
}
int LengthList(node Lhead)
{
int i=0;
node L=Lhead;
while(L->next!=NULL)
{
i++;
L=L->next;
}
return i;
}
node LocateList(int p,node Lhead)
{
node L;
L=Lhead;
while(p-1>0&&L!=NULL)
{
p--;
L=L->next;
}
if(p==1)
return L;
else
{
printf("Position is not exist!");
return NULL;
}
}
node InsertList(node Lhead)
{
int e,p;
node L1=Lhead,LInsert=NULL,L2=NULL;
T:
L1=Lhead;
LInsert=Create();
if(!LInsert==NULL)
LInsert->next=NULL;
else
printf("Fail to apply space!");
printf("Please input where you want to insert: ");
scanf(" %d",&p);
printf("Please input your elem: ");
scanf(" %d",&e);
LInsert->data=e;
L1=LocateList(p,L1);
if(L1==NULL)
{
printf("input wrong!\n");
free(LInsert);
LInsert=NULL;
goto T;
}
else
{
LInsert->next=L1->next;//新指针的后指针指向要插入位置后一个节点
L1->next=LInsert;//新指针要插入的位置的前一个节点的后指针指向新节点
LInsert->prior=L1;//新节点的前指针指向前一个节点
if(!LInsert->next==NULL)
{
L2=LInsert->next;//新指针赋值
L2->prior=LInsert;//后一个节点的前指针指向新节点
}
}
}
node DeleteList(node Lhead)
{
int p;
node L1=Lhead,L2=Lhead,L3=NULL;
T:
L1=Lhead;
printf("Please input where you want to delete.");
scanf(" %d",&p);
L1=LocateList(p,L1);
if(L1==NULL)
goto T;
else
{
while(L1->next!=L2)
{
L2=L2->next;
}
L3=L2->next;//指向删除节点的下一个节点
L3->prior=L1;//删除节点的下一个节点前指针指向删除节点的上一个节点
L1->next=L3;//删除节点的上一个节点前指针指向删除节点的下一个节点
free(L2);
L2=NULL;
}
}
3.循环链表
#include<stdio.h>
#include<stdlib.h>
typedef struct Lnode //定义链表
{
int data;
struct Lnode*next;
}Lnode,*node;
node CreateList();//构造链表头
int Isempty(node Lhead);//判断链表是否为空
void Traverse(node Lhead);//遍历链表
int LengthList(node Lhead);//求表长
node LocateList(int p,node Lhead);//寻找到位置
node InsertList(node Lhead);//插入数据
node DeleteList(node Lhead);//删除数据
int main()
{
int a=0,b=0,l=0;
char c;
node Lhead=NULL;
Lhead=CreateList();
do{
InsertList(Lhead);
printf("Do you want to add again?\n");
scanf(" %c",&c);
}while(c=='y'||c=='Y');
a=Isempty(Lhead);
if(a)//判断链表是否为空
printf("List isn't NULL!\n");
else
printf("List is NULL\n");
do{
printf("which function you want to choose?\n1.Travel list\n2.Lengthlist\n3.Insert\n4.Delete\n");
scanf(" %d",&b);
switch(b)
{
case 1:
Traverse(Lhead);
break;
case 2:
l=LengthList(Lhead);
printf("List's length is %d\n",l);
break;
case 3:
InsertList(Lhead);
break;
case 4:
DeleteList(Lhead);
break;
default:
exit(0);
}
}while(b!=5);
return 0;
}
node CreateList()
{
node Lhead;
Lhead=(node)malloc(sizeof(Lnode));
Lhead->next=Lhead;//链表指向自己的头节点,构成闭环
if(!Lhead==NULL)
return Lhead;
else
printf("Fail to apply space!");
}
int Isempty(node Lhead)
{
if(Lhead->next==Lhead)
return 0;
else
return 1;
}
void Traverse(node Lhead)
{
int p;
node L;
L=Lhead;
if(!Isempty(L))
{
printf("List is NULL!");
}
else
{
while(L->next!=Lhead)
{
L=L->next;
printf(" %d",L->data);
}
}
}
int LengthList(node Lhead)
{
int i=0;
node L=Lhead;
while(L->next!=Lhead)
{
i++;
L=L->next;
}
return i;
}
node LocateList(int p,node Lhead)
{
node L;
L=Lhead;
while(p-1>0&&L!=Lhead)
{
p--;
L=L->next;
}
if(p==1)
return L;
else
{
printf("Position is not exist!\n");
return NULL;
}
}
node InsertList(node Lhead)
{
int e,p;
node L1=Lhead,LInsert=NULL;
LInsert=CreateList();
T:
printf("Please input where you want to insert: ");
scanf(" %d",&p);
printf("Please input your elem: ");
scanf(" %d",&e);
LInsert->data=e;
L1=LocateList(p,L1);
if(L1==NULL)
{
printf("input wrong!\n");
goto T;
}
else
{
LInsert->next=L1->next;
L1->next=LInsert;
}
}
node DeleteList(node Lhead)
{
int p;
node L1=Lhead,L2=Lhead;
T:
printf("Please input where you want to delete.");
scanf(" %d",&p);
L1=LocateList(p,L1);
if(L1==NULL)
goto T;
else
{
while(L1->next!=L2)
{
L2=L2->next;
}
L1->next=L2->next;
free(L2);
L2=NULL;
}
}