顺序表和链表的比较:
比较项目 | 顺序表 | 链表 | |
---|---|---|---|
空间 | 存储空间 | 预先分配,会出现空间闲置或溢出现象 | 动态分配,不会出现空间闲置或溢出现象 |
存储密度 | 不用为表示结点间的逻辑关系而增加额外的存储开销,存储密度=1 | 需要借助指针来体现元素间的逻辑关系,存储密度<1 | |
时间 | 存取元素 | 随机存取,按位置访问元素的时间复杂度为O(1) | 顺序存取,时间复杂度O(n) |
插入、删除 | 平均移动约表中一半元素,时间复杂度O(n) | 不需移动元素,确定插入、删除位置后,时间复杂度O(1) | |
适用情况 | a. 表长变化不大,且能事先确定变化的范围 | a. 表长变化较大 | |
b. 很少进行插入、删除 | b. 频繁进行插入、删除 |
顺序表 SqList:
1. 初始化
void Init(SqList &L)
{
L.len=0;
}
2. 取值
void GetElem(SqList L,int i,ElemType &e)
{
if(i<1||i>L.len) return;
e=L.data[i];
}
3. 查找
int Find(SqList L,ElemType e)
{
for(i=1;i<=L.len;i++)
{
if(e==L.data[i]) return i;
}
return 0;
}
4. 插入
void Insert(SqList &L,int i,ElemType e)
{ //五步:i是否合法;表是否满;数据下移;取e;表长加一
if(i<1||i>L.len+1) return;
if(L.len>=SIZE-1) return;
for(int j=L.len;j>=i;j--)
{
L.data[j+1]=L.data[j];
}
L.data[i]=e;
L.len++;
}
5. 删除
void Del(SqList &L,int i) //三步:判断i是否合法;循环数据上移;表长减一
{
if(i<1||i>L.len) return;
for(int j=i;j<=L.len;j++)
{
L.data[j]=L.data[j+1];
}
L.len--;
}
6. 遍历
void Display(SqList L)
{
for(int i=1;i<=L.len;i++)
{
printf("%5d",L.data[i]);
}
printf("\n");
}
完整代码如下:
#include<stdio.h>
#define SIZE 101
typedef int ElemType;
typedef struct //数值和表长
{
ElemType data[SIZE];
int len;
}SqList;
//初始化
void Init(SqList &L) //长度=0
{
L.len=0;
}
//取值
void GetElem(SqList L,int i,ElemType &e)
{
if(i<1||i>L.len) return; //判断i是否合法
e=L.data[i];
}
//查找
int Find(SqList L,ElemType e)
{
for(int i=1;i<=L.len;i++) //从头依次查找e
if(e==L.data[i]) return i;
return 0;
}
//插入
void Insert(SqList &L,int i,ElemType e)
{
if(i<1||i>L.len+1) return; //判断i是否合法
if(L.len==SIZE-1) return; //判断表是否满
for(int j=L.len;j>=i;j--) //注意 >=
{
L.data[j+1]=L.data[j]; //自表底起元素依次往下移
}
L.data[i]=e;
L.len++; //表长+1
}
//删除
void Del(SqList &L,int i)
{
if(i<1||i>L.len) return; //判断i是否合法
for(int j=i;j<=L.len;j++)
{
L.data[j]=L.data[j+1]; //第i个元素以下的元素依次往上移
}
L.len--; //表长-1
}
//遍历
void Display(SqList L)
{
for(int i=1;i<=L.len;i++)
{
printf("%5d",L.data[i]);
}
printf("\n");
}
int main()
{
SqList s1,s2;
Init(s1);Init(s2);
Insert(s1,1,100);Insert(s1,2,50);Insert(s1,2,20);
Display(s1);
Del(s1,2);
Display(s1);
return 0;
}
单链表LinkList:
1. 初始化结点
void InitNode(LinkList *n)
{
n->next=NULL;
}
2. 初始化链表
void InitList(LinkList * &h)
{
h=new LinkList;
InitNode(h);
}
3. 创建新链表(前插法)
void Create(LinkList *&h)
{
LinkList *p=h,*t;
while(1)
{
ElemType e;
scanf("%d",&e);
if(e==0) break;
t=new LinkList;
InitNode(t);
t->data=e;
p->next=t;
p=p->next;
}
}
4. 遍历
void Display(LinkList *h)
{
LinkList *p=h->next;
while(p)
{
if(p->next==0)
printf("%d\n",p->data);
else
printf("%d->",p->data);
p=p->next;
}
}
5. 取值
void GetElem(LinkList *h,int i,ElemType &e)
{
LinkList *p=h->next; //指向首结点
int j=1;
while(p&&j<i){ //指针后移,直到p为空 或p指向第i个元素
p=p->next;
j++;
}
if(!p||i<1) return; //判断i是否合法 i>n或i<=0
e=p->data;
}
6. 查找
int Find(LinkList *h,ElemType e)
{
LinkList *p=h->next; //指向首结点
int j=1;
while(p&&p->data!=e) //指针后移,直到p为空 或p指向的元素=e
{
p=p->next;
j++;
}
if(!p) return 0;
return j;
}
7. 插入
void Insert(LinkList * &h,int i,ElemType e)
{
LinkList *p=h,*t; //p指向头结点
int j=0;
while(p&&j<i-1){ //指针后移,直到p为空 或p指向第i-1个元素
p=p->next;
j++;
}
if(!p||i<1) return; //判断i是否合法 i>n或i<=0
t=new LinkList;
InitNode(t);
t->data=e;
t->next=p->next; //指针修改语句***
p->next=t;
}
8. 删除
void Del(LinkList *&h,int i)
{
LinkList *p=h,*q; //p指向头结点
int j=0;
while(p->next&&i<1) return; //前后位置不可换 删除前为空链表或i不合法
q=p->next;
p->next=q->next;
delete q;
}
完整代码如下:
#include<stdio.h>
typedef int ElemType;
typedef struct node
{
ElemType data; //数据域
struct node *next; //指针域
}LinkList;
//初始化 结点
void InitNode(LinkList *n)
{
n->next=NULL; //指针域为空
}
//链表初始化
void InitList(LinkList * &h)
{
h=new LinkList;
InitNode(h);
}
//创建新链表 (前插法)
void Create(LinkList *&h)
{
LinkList *p=h,*t;
while(1)
{
ElemType e;
scanf("%d",&e);
if(e==0) break;
t=new LinkList;
InitNode(t);
t->data=e;
p->next=t;
p=p->next;
}
}
//遍历
void Display(LinkList *h)
{
LinkList *p=h->next;
while(p)
{
if(p->next==0)
printf("%d\n",p->data);
else
printf("%d->",p->data);
p=p->next;
}
}
//取值
void GetElem(LinkList *h,int i,ElemType &e)
{
LinkList *p=h->next; //指向首结点
int j=1;
while(p&&j<i){ //指针后移,直到p为空 或p指向第i个元素
p=p->next;
j++;
}
if(!p||i<1) return; //判断i是否合法 i>n或i<=0
e=p->data;
}
//查找
int Find(LinkList *h,ElemType e)
{
LinkList *p=h->next; //指向首结点
int j=1;
while(p&&p->data!=e) //指针后移,直到p为空 或p指向的元素=e
{
p=p->next;
j++;
}
if(!p) return 0;
return j;
}
//插入
void Insert(LinkList * &h,int i,ElemType e)
{
LinkList *p=h,*t; //p指向头结点
int j=0;
while(p&&j<i-1){ //指针后移,直到p为空 或p指向第i-1个元素
p=p->next;
j++;
}
if(!p||i<1) return; //判断i是否合法 i>n或i<=0
t=new LinkList;
InitNode(t);
t->data=e;
t->next=p->next; //指针修改语句***
p->next=t;
}
//删除
void Del(LinkList *&h,int i)
{
LinkList *p=h,*q; //p指向头结点
int j=0;
while(p->next&&i<1) return; //前后位置不可换 删除前为空链表或i不合法
q=p->next;
p->next=q->next;
delete q;
}
int main()
{
LinkList *h;
InitList(h);
Create(h);
Display(h);
ElemType e;
GetElem(h,4,e);printf("%d\n",e);
printf("%d\n",Find(h,-1));
Insert(h,3,100);
Display(h);
Del(h,2);
Display(h);
return 0;
}