数据结构——循环单链表【c语言版】

循环链表包括循环单链表和循环双链表

循环单链表的结点类型与非循环单链表相同,把非循环单链表改成循环单链表只需要将非循环单链表的尾结点next指针由原来的NULL改为指向头节点,自此就将非循环单链表形成看一个环,从表中的任一结点出发均可找到链表中其他的结点,这就是带头节点的循环单链表。

循环单链表的操作与单链表基本一致,差别在于遍历链表时,判别当前指针p是否指向表尾结点的终止条件不同:

        单链表:p->next != NULL

        循环单链表:p->next != h

如下是循环单链表:

数据结构——循环单链表【c语言版】_第1张图片

空循环单链表:数据结构——循环单链表【c语言版】_第2张图片

 

 下面附上循环单链表的完整代码:

#include 

typedef int ElemType;

typedef struct Node
{
	ElemType data;//存储线性表的元素值(1个) 
	struct Node *next;//存储后继元素节点的地址 
}SCLinkList;

/*
让最后一个节点的后继变成头节点 

为了方便操作,特别地加了一个头节点进来,类型和普通节点一样
data:不用 
next:存储第1个元素节点的地址 

执行语句p=p->next;一次,p的指向往后移动一个位置

空:h->next==h
最后一个节点:若p->next==h,说明p指向最后一个节点 
*/

/*
1.初始化
构造一个空的线性表 
*/
SCLinkList *InitList()
{
	SCLinkList *h;
	h=(SCLinkList *)malloc(sizeof(SCLinkList));
	h->next=h;
	return h;
}

/*
2.销毁 
*/
void DestroyList(SCLinkList *h)
{
	int ListDelete(SCLinkList *h,int i,ElemType *e);
	ElemType v;
	
	while(h->next!=h)//不空
	{
		//删除第1个元素节点
		ListDelete(h,1,&v); 
	} 
	free(h);
} 

/*
3.判断线性表是否为空
若为空,返回1;
否则,返回0 
*/
ListEmpty(SCLinkList *h)
{
	if(h->next==h)
	{
		return 1;
	} 
	else
	{
		return 0;
	}
} 

/*
4.求长度 
*/
int ListLength(SCLinkList *h)
{
	SCLinkList *p;
	int len;
	p=h;
	len=0;
	while(p->next!=h)
	{
		p=p->next;
		len=len+1;
	} 
	return len;
} 

/*
5.输出 
*/
void DispList(SCLinkList *h)
{
	SCLinkList *p;
	p=h; 
	printf("线性表的元素为:");
	while(p->next!=h)
	{
		p=p->next;
		printf("%d ",p->data); 
	} 
	printf("\n");
}

/*
6.取值
 
参数合法:i>=1 && i<=ListLength(h)
若参数合法,进行相关操作,返回1;
否则,提示,返回0  
*/
int GetElem(SCLinkList *h,int i,ElemType *e)
{
	SCLinkList *p;
	int j;
	
	if(i>=1 && i<=ListLength(h))
	{
		p=h;
		for(j=1;j<=i;j++)
		{
			p=p->next;
		} 
		*e=p->data;
		return 1;
	} 
	else
	{
		printf("参数错误!\n");
		return 0;
	}	
}

/*
7.查找
在线性表中查找是否存在值为e的元素,
若存在,返回该元素的位序
否则,返回0 
*/
int LocateElem(SCLinkList *h,ElemType e)
{
	SCLinkList *p;
	int len;
	p=h;
	len=0;
	while(p->next!=h)
	{
		p=p->next;
		len=len+1;
		if(p->data==e)
		{
			return len;
		}
	} 
	return 0;
} 

/*
8.添加 

参数合法:i>=1 && i<=ListLength(h)+1
若参数合法,进行相关操作,返回1;
否则,提示,返回0  
*/
int ListInsert(SCLinkList *h,int i,ElemType e)
{
	SCLinkList *p,*q;
	int j;
	
	if(i>=1 && i<=ListLength(h)+1)
	{
		//1.构造一个节点q,存储元素e
		q=(SCLinkList *)malloc(sizeof(SCLinkList));
		q->data=e;
		//2.让p指向第i-1个元素节点 
		p=h;
		for(j=1;j<=i-1;j++)
		{
			p=p->next;
		} 
		//3.添加
		q->next=p->next;
		p->next=q;
		return 1;
	}
	else
	{
		printf("参数错误!\n");
		return 0;
	} 
}

/*
9.删除

参数合法:i>=1 && i<=ListLength(h)
若参数合法,进行相关操作,返回1;
否则,提示,返回0  
*/
int ListDelete(SCLinkList *h,int i,ElemType *e)
{
	SCLinkList *p,*q;
	int j;
	
	if(i>=1 && i<=ListLength(h))
	{
		//1.让p指向第i-1个
		p=h;
		for(j=1;j<=i-1;j++)
		{
			p=p->next;
		} 
		//2.让q指向第i个
		q=p->next;
		//3.把要删除的元素值存储到*e中 
		*e=q->data;
		//4.删除
		p->next=q->next;
		//5.释放存储空间
		free(q); 
		return 1;
	}
	else
	{
		printf("参数错误!\n");
		return 0;
	} 	
} 
/*
变量先定义,再赋初值,才能使用 
*/
int main()
{
	/*
	int a;
	int b;
	
	b=a*10;
	printf("%d\n",b);*/
	
	/*
	int *p;
	
	p=(int *)malloc(sizeof(int));
	
	*p = 123;
	
	printf("%d\n",*p);
	
	free(p);
	*/
	return 1;
} 

你可能感兴趣的:(数据结构,c语言,数据结构,链表)