其他分享
首页 > 其他分享> > 单循环链表(C语言)

单循环链表(C语言)

作者:互联网

单向循环链表(C语言)

  1. 实质:将表尾的next指向头部的Head,以此完成表的循环。
  2. 查找优化:从表尾开始查找,这样查找表尾和表头的时间会大大缩短。避免了以表土为起点时,查找表尾需要O(n)时间来查找。
  3. 整个表建立在指针实现表的基础上增加了表尾Last元素,和表头Head元素。
  4. 代码如下:
#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);

	
	
}
  1. 运行结果如下:
    在这里插入图片描述

标签:Last,Head1,int,Snode,next,链表,单循环,Last1,C语言
来源: https://blog.csdn.net/Mpnet/article/details/121313148