顺序表与单链表
优缺点比较
顺序表 | 单链表 | |
---|---|---|
存储分配方式 | 顺序存储结构(类似于数组) | 链式存储结构 |
时间性能 | 插入与删除时间为o(n) 查找时间为o(1) | 插入图与删除时间为o(1) 查找时间为o(n) |
空间性能 | 需要预分配空间 | 只要有就可分配,元素个数不受限制 |
顺序表
typedef struct {
int data[max];
int length;
}List;
获取元素
int GetElem(List L,int i,int *e) {
if(L.length == 0 || i < 1 || i > L.length)
return 0;
*e = L.data[i - 1];
return 1;
}
插入操作
int ListInsert(List *L,int i,int e) {
int k;
if(L->length == max) // 顺序表已满
return 0;
if(i < 1 || i > L->length + 1) // i不在范围
return 0;
if(i <= L->length) { // 未在表尾插入
for(k = L->length - 1; k >= i - 1; k--)
L->data[k + 1] = L->data[k];
}
L->data[i - 1] = e;
L->length++;
return 1;
}
删除操作
int ListDelete(List *L,int i) {
int k;
if(L->length == 0) // 顺序表为空
return 0;
if(i < 1 || i > L->length) // 删除位置不正确
return 0;
if(i < L->length) {
for(k = i; k < L->length; k++)
L->data[k - 1] = L->data[k];
}
L->length--;
return 1;
}
单链表
typedef struct Node {
int data;
struct Node *next;
}Node;
typedef struct Node *LinkList;
假设p为线性表第i个元素的指针,p->data是一个数据元素,p->next是一个指针,指向第i+1个元素。
插入操作
s->next = p->next; p->next = s;
两句代码顺序不可颠倒。因为会使p->next覆盖成s的地址。
// 第i个位置插入元素elem
void Insert(List L,int i,int elem) {
List p,s;
int j;
p = L;
while(p != NULL && j < i - 1) { // 找第 i 个结点
p = p->next;
++j;
}
if( !p || j >= i) { // 第 i 个结点不存在
printf("位置不合理");
return;
}
s = (LNode *)malloc(sizeof(Node)); // 生成新结点
s->data = elem;
s->next = p->next; // p的后继 赋给 s 的后继
p->next = s; // s 赋给 p的后继
}
删除操作
p->next = p->next->next;
// 删除L的第i个结点
void Delete(List L,int i) {
LNode *p,*q;
int j = 0;
p = L;
while(p->next != NULL && j < i - 1) { // 找第 i 个结点
p = p->next;
++j;
}
if(!(p->next) || j >= i) { // 第 i 个结点不存在
printf("第%d个结点不存在\n",i);
return;
}
q = p->next;
p->next = q->next; // q的后继 赋给 p 的后继
free(q); // 回收该结点,释放内存
}