线性表-链表结构与顺序存储结构优缺点对比
空间性能
- 顺序存储结构需要预先分配存储空间,分太大,浪费空间;分太小,发生上溢出;
- 单链表不需要分配存储空间,只要有就可以分配,元素个数也不受限制;
时间复杂度
查找
- 顺序存储O(1)
- 单链表O(n)
插入和删除
- 顺序存储结构需要平均移动一个表长一半的元素 O(n)
- 单链表O(1)
单向循环链表

- 链表的结点数据结构是一个存储数据的int类型data以及指向下一个结点的指针next
typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;/* ElemType类型根据实际情况而定,这里假设为int */
//定义结点
typedef struct Node{
ElemType data;
struct Node *next;
}Node;
typedef struct Node * LinkList;

循环链表的创建与插入
2种情况
/*
*L 就是初始指针
*/
status CreateList(LinkList *L) {
//产生头结点,并使用L指向此头结点
*L = (LinkList)malloc(sizeof(Node));
//存储空间分配失败
if(*L == NULL) return ERROR;
//将头结点的指针域置空
(*L)->next = NULL;
return OK;
}
1 创建
- YES 新节点;新节点next->自身
- NO 链表结尾的位置;尾节点next->新节点; 新的节点next->首元结点
2 新增(插入)数据
1 插入位置在首元结点上
- 判断插入位置是否在首元结点上
- 创建新节点,并赋值给新节点
2 插入位置在其他位置
- 不用判断是在中间插入还是在尾部插入,都是一样的

循环链表插入
Status ListInsert(LinkeList *L,int place,int num){
LinkList temp,target;
int i;
if(place == 1){
//1 创建temp
//2 链表中最后一个结点位置
//3 新的结点next指向头结点
//4 尾节点next指向新的头结点
//5 让*L 指向temp
temp = (LinkList)malloc(sizeof(Node));
if(temp == NULL) return ERROR;
temp->data = num;
for(target = *L;target->next != *L;target = target->next);
temp->next = *L;
target->next = temp;
}else{
//1 创建temp temp就是插入的新节点
//2 找到插入的前一个位置 target
//3 新节点的next指向target-next
//4 target->next = temp target就是插入位置的前一个结点
temp = (LinkList)malloc(sizeof(Node));
if(temp == NULL) return ERROR;
temp->data = num;
for(i=1,target = *L;target->next != *L && i!=place-1;target = target->next;i++); //避免循环多次遍历链表
temp->next = target->next;
target-next = temp;
}
return OK;
}

循环链表的删除
直接上代码
/*
L 指向链表的指针
place 删除的位置
*/
Status LinkListDelete(LinkList *L,int place){
LinkList temp,target;
int i;
temp = *L;
if(temp == NULL) return ERROR;
if(place == 1){
//如果删除的是首元结点
//1 找到尾结点
//2 新节点作为首结点
for(target = *L;target->next != *L;target = target->next);
*L = (*L)->next;
target->next = *L;
free(temp); //还要释放删除的结点
}else{ //如果是其他结点
//1 删除的位置
//2 找到删除的前面的结点 target
//3 创建temp指向target的下一个结点
//4 释放temp
for(i=1,target = *L;target->next != *L && i!=place-1;i++){
target = target->next;
}
temp = target ->next;
target->next = temp->next;
free(temp);
}
return OK;
}
循环链表的查询
单向循环链表的查询
int findValue(LinkList L,int value){
int i = 1;
LinkList p;
p = L;
while(p->data != value && p->next != L){
i++;
p = p->next;
}
if(p->next == L && p->data !=value){
return -1;
}
return i;
}
单链表查询倒数第k个节点方案
int Search_k(LinkList L,int k){
if(L==NULL||L->next==NULL)
return 0;
int count=0;
LinkList p,q;
p=q=A->next;
while(q){
if(count<k){
count++;
}else{
p=p->next;
}
q=q->next;
}
if(count<k) //当q=null的时候count还没有达到k说明k大于链表总长度
return 0;
printf("%d\n",p->data);
return 1;
未完待续