单循环链表(C语言)
作者:互联网
单向循环链表(C语言)
- 实质:将表尾的next指向头部的Head,以此完成表的循环。
- 查找优化:从表尾开始查找,这样查找表尾和表头的时间会大大缩短。避免了以表土为起点时,查找表尾需要O(n)时间来查找。
- 整个表建立在指针实现表的基础上增加了表尾Last元素,和表头Head元素。
- 代码如下:
#include<stdio.h>
#include<stdlib.h>
typedef int ListItem;
typedef struct snode *Snode;
typedef struct snode{
ListItem element;
Snode next;
}Simuel;
Snode ListInsert(Snode Last1,int *p,ListItem x,int k)//Last为指向表尾的指针,这个根据插入的不同情况改变,p是表的长度,接下来是值,和位置k
{ //表的初始化要放到主函数来做了
int cnt=0;
Snode S = NULL;
Snode Last = Last1;
Snode I = (struct snode *)malloc(sizeof (struct snode));//用来分配空间的指针
if(k >= *p ){
I->next = Last->next;//将新加的表尾指向表头,从旧表尾那里获取
Last->next = I;
Last1 = I;//表尾变成新在表尾插入的节点I
}
else{//表内插入
while(cnt<k){
Last = Last->next;//找到插入的那个位置
cnt++;
}
S = Last->next;//插入的那个位置的后一个
Last->next = I;
I->next = S;
}
*p = *p +1;//添加完成之后,表长+1;
I -> element = x;
return Last1;
}
int ListFind(Snode Last1,ListItem x,int *p)
{
int i = 0;
Snode Last = Last1;
while( Last->element != x){
i++;
Last = Last->next;
}
//怎么解决查找表尾时候的问题
return i;//返回0时说明该元素在表尾
}
Snode ListDellete(Snode Last1,ListItem x,int *p)//此函数无法删除表头
{
int i = ListFind(Last1,x,p);
printf("i==%d",i);
printf("进入函数\n");
int cnt = 0;
Snode S = NULL;
Snode Last = Last1;
if(i != 0) {
S = Last;
while(cnt < i-1){//删除位置前一个
Last = Last->next;
cnt++;
}
cnt = 0;
while(cnt<i){//删除位置
S = S -> next;
cnt ++;
}
Last ->next = S -> next;
free(S);
}
else {//对删除last所在的节点的特殊处理
S = Last;
while(S -> next != Last){
S = S ->next; //寻找表尾的一个
}
S -> next = Last ->next;
Last1 = S;
free(Last);
}
*p = *p -1;
return Last1;
}
Snode ListHead(Snode Last1,Snode Head1,int *p)//此函数用于表头删除
{
Snode S = NULL;
Last1 ->next = Head1 ->next;
S= Head1 ->next;
free(Head1);
*p = *p -1;
return S;
}
void ListTravel(Snode Head1)
{
Snode Head = Head1;
printf("现在输出一遍表的元素\n");
do{
printf(" %d ",Head ->element);
Head = Head -> next;
}while(Head ->next != Head1->next);
printf("\n");
}
void ListModify(Snode Last1,int k,int *p,int va) // 这里的k为位置
{
Snode Last = Last1;
int i = 0;
int b=va;
if(k == *p) {
}
else{
while(i<k){
Last = Last -> next;
i++;
}
}
Last ->element = va;
}
int main()
{
Snode Head1 = NULL;
Snode Last1 = NULL;
int position = 0;
int a = 2;
int *p;
p =&a;
Last1 = (struct snode *)malloc(sizeof(struct snode));
Head1 = (struct snode *)malloc(sizeof(struct snode));
Head1 ->next = Last1;//初始化一个最小长度的单循环链表
Last1->next = Head1;
Head1 ->element = 1;
Last1 -> element =2;
Last1 = ListInsert(Last1,p,4,3);
ListTravel(Head1);
Last1 = ListInsert(Last1,p,5,4);
ListTravel(Head1);
Last1 = ListInsert(Last1,p,6,5);
ListTravel(Head1);
printf("现在验证表内插入\n");
Last1 = ListInsert(Last1,p,77,3);
ListTravel(Head1);
Last1 = ListInsert(Last1,p,99,4);
ListTravel(Head1);
printf("现在验证删除\n");
Last1 = ListDellete(Last1,77,p);
ListTravel(Head1);
Last1 = ListDellete(Last1,99,p);
ListTravel(Head1);
printf("现在验证删除表尾元素\n");
Last1 = ListDellete(Last1,6,p);
ListTravel(Head1);
printf("现在验证删除表尾元素\n");
Last1 = ListDellete(Last1,5,p);
ListTravel(Head1);
printf("现在验证删除表首元素\n");
Head1 = ListHead(Last1,Head1,p);
ListTravel(Head1);
printf("现在验证修改表内1号元素为100\n");
ListModify(Last1,1,p,100);
ListTravel(Head1);
printf("现在验证产找函数\n");
position = ListFind(Last1,100,p);
if(position == 0) position = *p;//查找表尾的时候会返回0,与删除表尾的功能不能不兼容。所以在主函数手动判断一次
printf("100这个元素位于第%d位\n",position);
}
- 运行结果如下:
标签:Last,Head1,int,Snode,next,链表,单循环,Last1,C语言 来源: https://blog.csdn.net/Mpnet/article/details/121313148