赞
踩
线性表的顺序存储实现称为顺序表。
线性表的链式存储实现称为链式表。
顺序表的数据在内存地址中连续,采用数组实现。
将数组封装在结构体中:
typedef int Position; // 使用typedef为int定义了一个别名为Position,记录数组中最后一个元素的位置
struct LNode { //定义了一个结构体
ElementType Data[MAXSIZE]; //将这个数组封装在结构体中
Position Last; //Last记录数组中最后一个元素的位置
};
typedef struct LNode* PtrToLNode; //为指向结构体LNode的指针定义一个别名PtrToLNode
typedef PtrToLNode List; //为指向结构体LNode的指针定义一个别名List
Length函数:
int Length(List L){ //返回线性表L的长度。
return (L->Last + 1);
}
FindKth函数:
ElementType FindKth(List L, int i){ //返回L中位序为 i 的元素
return L->Data[i-1];
}
MakeEmpty函数:
List MakeEmpty(){ //初始化一个新的空线性表
List L;
L = (List)malloc(sizeof(struct LNode));
L->Last = -1;
return L;
}
Find函数:
Position Find(List L, ElementType X){
Position i = 0;
while(i <= L->Last && L->Data[i]!=X) i++;
if(i>L->Last) return -1;
else return i;
}
Insert函数:
bool Insert(List L, ElementType X, int i){ Position j; if(L->Last==MAXSIZE-1){ printf("表满\n"); return false; } if(i<1 || i>L->Last+2){ //当 i 等于1的时候插入在表头,当 i 等于Last+2的时候,插入在表尾 printf("位序不合法\n"); return false; } for(j=L->Last; j>=i-1; j--) //移动从i-1开始后面的元素 L->Data[j+1]=L->Data[j]; L->Data[i-1]=X; L->Last++; //Last指向最后一个元素 return true; }
Delete函数:
bool Delete(List L, int i){
Position j;
if(i<1||i>L->Last+1){
printf("位序%d不存在元素\n",i);
return false;
}
for(j=i;j<=L->Last;j++)
L->Data[j-1]=L->Data[j];
L->Last--;
return true;
}
测试程序:
操作系统:Ubuntu
编译器:gcc (不同编译器代码可能略有不同)
#include<stdio.h> #include<stdlib.h> //包含malloc函数的声明 //宏定义 #define MAXSIZE 15 #define ERROR -1 typedef enum {false, true} bool; //枚举类型,false的值为0,true的值为1,并取别名为bool typedef int ElementType; //假设ElementType为int型 typedef int Position; // 使用typedef为int定义了一个别名为Position,记录数组中最后一个元素的位置 struct LNode { //定义了一个结构体 ElementType Data[MAXSIZE]; //将这个数组封装在结构体中 Position Last; //Last记录数组中最后一个元素的位置 }; typedef struct LNode* PtrToLNode; //为指向结构体LNode的指针定义一个别名PtrToLNode typedef PtrToLNode List; //函数声明 List MakeEmpty(); ElementType FindKth(List L, int i); Position Find(List L, ElementType X); bool Insert(List L, ElementType X, int i); bool Delete(List L, int i); int Length(List L); //主函数 int main(){ int i, input; List L = MakeEmpty(); //插入数据 for(i=0; i<15; i++){ scanf("%d",&input); if(Insert(L,input,i+1)) printf("%d插入位序%d成功\n",input,i+1); else printf("插入失败\n"); } //输出此时顺序表的长度 printf("当前顺序表的表长为:%d\n",Length(L)); //输出数据 for(i=0;i<15;i++) printf("位序%d的数据为%d\n",i+1,FindKth(L,i+1)); //删除数据 if(Delete(L,i)) printf("位序%d数据删除成功\n",i); else printf("删除失败\n"); i=-2; if(Delete(L,i)) printf("位序%d数据删除成功\n",i); else printf("删除失败\n"); i=1; if(Delete(L,i)) printf("位序%d数据删除成功\n",i); else printf("删除失败\n"); i=6; if(Delete(L,i)) printf("位序%d数据删除成功\n",i); else printf("删除失败\n"); //输出此时顺序表的长度 printf("当前顺序表的表长为:%d\n",Length(L)); //插入数据 if(Insert(L,i,4)) printf("%d插入位序%d成功\n",i,4); else printf("插入失败\n"); if(Insert(L,i,30)) printf("%d插入位序%d成功\n",i,30); else printf("插入失败\n"); //查找位置 Position p = Find(L,i); if(p==ERROR) printf("数据%d不在线性表中\n",i); else printf("数据%d的位置为%d\n",i,p+1); p = Find(L,999999999); if(p==ERROR) printf("数据%d不在线性表中\n",999999999); else printf("数据%d的位置为%d\n",i,p+1); return 0; } int Length(List L){ return (L->Last + 1); } ElementType FindKth(List L, int i){ return L->Data[i-1]; } List MakeEmpty(){ List L; L = (List)malloc(sizeof(struct LNode)); L->Last = -1; return L; } Position Find(List L, ElementType X){ Position i = 0; while(i <= L->Last && L->Data[i]!=X) i++; if(i>L->Last) return ERROR; else return i; } bool Insert(List L, ElementType X, int i){ Position j; if(L->Last==MAXSIZE-1){ printf("表满\n"); return false; } if(i<1 || i>L->Last+2){ //当 i 等于1的时候插入在表头,当 i 等于Last+2的时候,插入在表尾 printf("位序不合法\n"); return false; } for(j=L->Last; j>=i-1; j--) //移动从i-1开始后面的元素 L->Data[j+1]=L->Data[j]; L->Data[i-1]=X; L->Last++; //Last指向最后一个元素 return true; } bool Delete(List L, int i){ Position j; if(i<1||i>L->Last+1){ printf("位序%d不存在元素\n",i); return false; } for(j=i;j<=L->Last;j++) L->Data[j-1]=L->Data[j]; L->Last--; return true; }
测试程序运行结果:
顺序表的数据在内存中连续,插入和删除操作都需要移动数组中的数据,效率不高。可以采用链表,插入和删除只需要修改节点中指针变量的值即可。链式表当中的数据,在内存地址中,连续还是不连续没有特别要求。
单向链表的结构体:
struct LNode {
ElementType Data;
struct LNode* Next;
};
typedef struct LNode* PtrToLNode;
typedef PtrToLNode Position;
typedef PtrToLNode List;
不带头节点的链式表第一个节点中存放数据。
List MakeEmpty(); //初始化一个新的空线性表。
ElementType FindKth(List L, int i); //返回L中位序为 i 的元素。
Position Find(List L, ElementType X); //返回线性表L中第一次出现X的位置;若不存在返回错误信息。
List Insert(List L, ElementType X, int i); //在L指定位序 i 前插入一个新的元素X;成功则返回头节点,否则返回ERROR。
List Delete(List L, int i); //从L中删除指定位序 i 的元素,成功返回头节点,否则返回ERROR。
int Length(List L); //返回线性表L的长度。
MakeEmpty函数:
List MakeEmpty(){
List L=NULL;
return L;
}
Length函数:
int Length(List L){
Position p; //指向结构体的指针
int cnt = 0; //初始化cnt的值为0
p = L; //令p等于头节点
while(p){ //while循环,从头节点开始循环
p = p -> Nest; //改变p的值,移动到下一个节点
cnt++; //每遍历一个节点cnt的值加1
}
return cnt; //返回节点总数
}
FindKth函数:
ElementType FindKth(List L, int i){ //返回L中位序为 i 的元素
Position p;
int cnt = 1;
p=L;
while(p&&cnt<i){
p=p->Next;
cnt++;
}
if((cnt==i)&&p) //如果cnt等于K且p不为空,则找到了
return p->Data;
else
return ERROR;
}
Find函数:
Position Find(List L, ElementType X){
Position p=L;
while(p&&p->Data!=X) p=p->Next;
if(p) return p;
else return ERROR;
}
Insert函数:
List Insert(List L, ElementType X, int i){ Position tmp, pre; tmp=(Position)malloc(sizeof(struct LNode)); tmp->Data=X; if(i==1){ tmp->Next = L; return tmp; } else { int cnt=1; pre = L; while(pre&&cnt<i-1){ pre=pre->Next; cnt++; } if(pre==NULL||cnt!=i-1){ printf("插入位置参数错误\n"); free(tmp); return ERROR; } else { tmp->Next=pre->Next; pre->Next=tmp; return L; } } }
Delete函数:
List Delete(List L, int i){ Position pre,tmp; int cnt=1; pre=L; while(pre&&cnt<i-1){ pre=pre->Next; cnt++; } if(pre==NULL||pre->Next==NULL){ //删除的位序错误 printf("删除位置参数错误\n"); return ERROR; } else { if(i==1){ //如果删除的是第一个节点 tmp=pre->Next; free(pre); return tmp; } else { //不是第一个节点 tmp=pre->Next; pre->Next=tmp->Next; free(tmp); return L; } } }
测试程序:
编译器:gcc
#include<stdio.h> #include<stdlib.h> #define ERROR NULL typedef int ElementType; struct LNode { ElementType Data; struct LNode* Next; }; typedef struct LNode* PtrToLNode; typedef PtrToLNode Position; typedef PtrToLNode List; List MakeEmpty(); //初始化一个新的空线性表。 ElementType FindKth(List L, int i); //返回L中位序为 i 的元素。 Position Find(List L, ElementType X); //返回线性表L中第一次出现X的位置;若不存在返回错误信息。 List Insert(List L, ElementType X, int i); //在L指定位序 i 前插入一个新的元素X;成功则返回头节点,否则返回ERROR。 List Delete(List L, int i); //从L中删除指定位序 i 的元素,成功返回头节点,否则返回ERROR。 int Length(List L); //返回线性表L的长度。 int main(){ int i,n,x; List L,flag; L=MakeEmpty(); if(Delete(L,2)) printf("删除位序元素成功\n"); else printf("删除位序错误或链表为空\n"); if(Insert(L,6,3)) printf("插入元素成功\n"); else printf("插入位序错误\n"); scanf("%d",&n); for(i=1;i<=n;i++){ scanf("%d",&x); if(flag=Insert(L,x,i)) { printf("插入元素成功\n"); L=flag; } else printf("插入位序错误\n"); } for(i=1;i<=n;i++){ printf("%d ",FindKth(L,i)); } putchar('\n'); if(flag=Insert(L,666,1)){ printf("插入元素成功\n"); L=flag; } else printf("插入位序错误\n"); if(flag=Insert(L,999,4)){ printf("插入元素成功\n"); L=flag; } else printf("插入位序错误\n"); if(flag=Insert(L,888,20)){ printf("插入元素成功\n"); L=flag; } else printf("插入位序错误\n"); for(i=1;i<=7;i++){ printf("%d ",FindKth(L,i)); } putchar('\n'); if(flag=Delete(L,2)){ printf("删除元素成功\n"); L=flag; } else printf("删除位序错误\n"); if(flag=Delete(L,100)){ printf("删除元素成功\n"); L=flag; } else printf("删除位序错误\n"); flag=Find(L,666); printf("%d\n",flag->Data); return 0; } List MakeEmpty(){ List L=NULL; return L; } ElementType FindKth(List L, int i){ //返回L中位序为 i 的元素 Position p; int cnt = 1; p=L; while(p&&cnt<i){ p=p->Next; cnt++; } if((cnt==i)&&p) //如果cnt等于K且p不为空,则找到了 return p->Data; else return ERROR; } Position Find(List L, ElementType X){ Position p=L; while(p&&p->Data!=X) p=p->Next; if(p) return p; else return ERROR; } List Insert(List L, ElementType X, int i){ Position tmp, pre; tmp=(Position)malloc(sizeof(struct LNode)); tmp->Data=X; if(i==1){ tmp->Next = L; return tmp; } else { int cnt=1; pre = L; while(pre&&cnt<i-1){ pre=pre->Next; cnt++; } if(pre==NULL||cnt!=i-1){ printf("插入位置参数错误\n"); free(tmp); return ERROR; } else { tmp->Next=pre->Next; pre->Next=tmp; return L; } } } List Delete(List L, int i){ Position pre,tmp; int cnt=1; pre=L; while(pre&&cnt<i-1){ pre=pre->Next; cnt++; } if(pre==NULL||pre->Next==NULL){ //删除的位序错误 printf("删除位置参数错误\n"); return ERROR; } else { if(i==1){ //如果删除的是第一个节点 tmp=pre->Next; free(pre); return tmp; } else { //不是第一个节点 tmp=pre->Next; pre->Next=tmp->Next; free(tmp); return L; } } } int Length(List L){ Position p; //指向结构体的指针 int cnt = 0; //初始化cnt的值为0 p = L; //令p等于头节点 while(p){ //while循环,从头节点开始循环 p = p -> Next; //改变p的值,移动到下一个节点 cnt++; //每遍历一个节点cnt的值加1 } return cnt; //返回节点总数 }
测试程序运行结果:
带头节点的链式表第一个节点中不存放数据。
List MakeEmpty(); //初始化一个新的空线性表。
ElementType FindKth(List L, int i); //返回L中位序为 i 的元素。
Position Find(List L, ElementType X); //返回线性表L中第一次出现X的位置;若不存在返回错误信息。
bool Insert(List L, ElementType X, int i); //在L指定位序 i 前插入一个新的元素X;成功则返回true,否则返回false。
bool Delete(List L, int i); //从L中删除指定位序 i 的元素,成功返回true,否则返回false。
int Length(List L); //返回线性表L的长度。
MakeEmpty函数:
List MakeEmpty(){ //申请第一个节点的内存空间,但是不存放数据
List L;
L = (List)malloc(sizeof(struct LNode));
L -> Next = NULL;
return L;
}
Length函数:
int Length(List L){
int cnt=0;
while(L){
L=L->Next;
cnt++;
}
return cnt;
}
FindKth函数:
ElemenetType FindKth(List L, int i){
Position p;
int cnt=0;
p=L;
while(p&&cnt<i){
p=p->Next;
cnt++;
}
if((cnt==i)&&p)
return p->Data;
else
return ERROR;
}
Find函数:
Position Find(List L, ElementType X){
Position p=L;
while(p&&p->Data!=X)
p=p->Next;
if(p)
return p;
else
return ERROR;
}
Insert函数:
bool Insert(List L, ElementType X, int i){ Position tmp, pre; int cnt=0; pre = L; while(pre&&cnt<i-1){ pre=pre->Next; cnt++; } if(pre==NULL||cnt!=i-1){ printf("插入位置参数错误\n"); return false; } else{ tmp=(Position)malloc(sizeof(struct LNode)); tmp->Data = X; tmp->Next=pre->Next; pre->Next=tmp; return true; } }
Delete函数:
bool Delete(List L, int i){ Position tmp, pre; int cnt=0; pre=L; while(pre&&cnt<i-1){ pre=pre->Next; cnt++; } if(pre==NULL||cnt!=i-1||pre->Next==NULL){ printf("删除位置参数错误\n"); return false; } else{ tmp=pre->Next; pre->Next=tmp->Next; free(tmp); return true; } }
测试程序:
编译器:gcc
#include<stdio.h> #include<stdlib.h> #define ERROR NULL typedef int ElementType; typedef enum {false, true} bool; struct LNode { ElementType Data; struct LNode* Next; }; typedef struct LNode* PtrToLNode; typedef PtrToLNode Position; typedef PtrToLNode List; List MakeEmpty(); //初始化一个新的空线性表。 ElementType FindKth(List L, int i); //返回L中位序为 i 的元素。 Position Find(List L, ElementType X); //返回线性表L中第一次出现X的位置;若不存在返回错误信息。 bool Insert(List L, ElementType X, int i); //在L指定位序 i 前插入一个新的元素X;成功则返回头节点,否则返回ERROR。 bool Delete(List L, int i); //从L中删除指定位序 i 的元素,成功返回头节点,否则返回ERROR。 int Length(List L); //返回线性表L的长度。 int main(){ int i, input; List L = MakeEmpty(); //插入数据 for(i=0; i<15; i++){ scanf("%d",&input); if(Insert(L,input,i+1)) printf("%d插入位序%d成功\n",input,i+1); else printf("插入失败\n"); } //输出此时顺序表的长度 printf("当前顺序表的表长为:%d\n",Length(L)); //输出数据 for(i=0;i<15;i++) printf("位序%d的数据为%d\n",i+1,FindKth(L,i+1)); //删除数据 if(Delete(L,i)) printf("位序%d数据删除成功\n",i); else printf("删除失败\n"); i=-2; if(Delete(L,i)) printf("位序%d数据删除成功\n",i); else printf("删除失败\n"); i=1; if(Delete(L,i)) printf("位序%d数据删除成功\n",i); else printf("删除失败\n"); i=6; if(Delete(L,i)) printf("位序%d数据删除成功\n",i); else printf("删除失败\n"); //输出此时顺序表的长度 printf("当前顺序表的表长为:%d\n",Length(L)); //插入数据 if(Insert(L,i,4)) printf("%d插入位序%d成功\n",i,4); else printf("插入失败\n"); if(Insert(L,i,30)) printf("%d插入位序%d成功\n",i,30); else printf("插入失败\n"); //查找位置 Position p = Find(L,i); if(p==ERROR) printf("数据%d不在线性表中\n",i); else printf("数据%d的位置为%d\n",i,p+1); p = Find(L,999999999); if(p==ERROR) printf("数据%d不在线性表中\n",999999999); else printf("数据%d的位置为%d\n",i,p+1); return 0; } List MakeEmpty(){ //申请第一个节点的内存空间,但是不存放数据 List L; L = (List)malloc(sizeof(struct LNode)); L -> Next = NULL; return L; } int Length(List L){ int cnt=0; while(L){ L=L->Next; cnt++; } return cnt-1; } ElementType FindKth(List L, int i){ Position p; int cnt=0; p=L; while(p&&cnt<i){ p=p->Next; cnt++; } if((cnt==i)&&p) return p->Data; else return ERROR; } Position Find(List L, ElementType X){ Position p=L; while(p&&p->Data!=X) p=p->Next; if(p) return p; else return ERROR; } bool Insert(List L, ElementType X, int i){ Position tmp, pre; int cnt=0; pre = L; while(pre&&cnt<i-1){ pre=pre->Next; cnt++; } if(pre==NULL||cnt!=i-1){ printf("插入位置参数错误\n"); return false; } else{ tmp=(Position)malloc(sizeof(struct LNode)); tmp->Data = X; tmp->Next=pre->Next; pre->Next=tmp; return true; } } bool Delete(List L, int i){ Position tmp, pre; int cnt=0; pre=L; while(pre&&cnt<i-1){ pre=pre->Next; cnt++; } if(pre==NULL||cnt!=i-1||pre->Next==NULL){ printf("删除位置参数错误\n"); return false; } else{ tmp=pre->Next; pre->Next=tmp->Next; free(tmp); return true; } }
运行截图:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。