循环链表

目录

  • 前言
  • 一、循环链表的定义
  • 二、算法实现
  • 小结


前言

**单链表的局限性**
  1. 单链表可以用于表示任意的线性关系
  2. 有些线性关系是循环的,即没有队尾元素。

一、循环链表的定义

将单链表中最后一个数据元素的next指针指向第一个元素

循环链表拥有单链表的所有操作

  1. 创建链表
  2. 销毁链表
  3. 获取链表长度
  4. 清空链表
  5. 获取第pos个元素操作
  6. 插入元素到pos位置
  7. 删除第pos位置的元素

游标的定义
在循环链表中可以定义一个“当前“指针,这个指针通常称为游标,可以通过这个游标来遍历链表中的所有操作

循环链表的特殊操作

  1. 获取当前游标指向的数据元素
  2. 将游标重置指向链表中的第一个数据元素
  3. 将游标移动指向到链表中的下一个数据元素
  4. 直接指定删除链表中的某个数据元素
CircleListNode* CircleList_Current(CircleList* list);
CircleListNode* CircleList_Reset(CircleList* list);
CircleListNode* CircleList_Next(CircleList* list);
CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node);

二、算法实现

# ifndef _CIRCLELIST_H_
# define _CIRCLELIST_H_

typedef void CircleList;
typedef struct _tag_CircleListNode CircleListNode;

struct _tag_CircleListNode{
	CircleListNode* next;
};

CircleList* CircleList_Create();

void CircleList_Destroy(CircleList* list);

void CircleList_Clear(CircleList* list);

int CircleList_Length(CircleList* list);

int CircleList_Insert(CircleList* list, CircleListNode* node, int pos);

CircleListNode* CircleList_Get(CircleList* list, int pos);

CircleListNode* CircleList_Delete(CircleList* list, int pos);

CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node);

CircleListNode* CircleList_Reset(CircleList* list);

CircleListNode* CircleList_Current(CircleList* list);

CircleListNode* CircleList_Next(CircleList* list);

#endif
#include 
#include 
#include "CircleList.h"

typedef struct _tag_CircleList{
	CircleListNode header;
	int length;	
	CircleListNode* slider;
}TCircleList;

CircleList* CircleList_Create(){
	TCircleList* ret = (TCircleList*)malloc(sizeof(TCircleList));
	
	if(ret !=NULL){
	ret->length = 0;
	ret->header.next=NULL; 
	ret->slider = NULL;
	} 
	return ret;
}

void CircleList_Destroy(CircleList* list){
	free(list);
}

void CircleList_Clear(CircleList* list){
	TCircleList* sList = (TCircleList*) list;
	
	if(sList != NULL)
	{
		sList->header.next = NULL;
		sList->length = 0;
		sList->slider =NULL;
	}
}

int CircleList_Length(CircleList* list)
{
	TCircleList* sList = (TCircleList*)list;
	int ret = -1; 
	
	if(sList != NULL)
	{
		ret = sList->length;
	}
	return ret;
}

int CircleList_Insert(CircleList* list, CircleListNode* node, int pos)
{
	TCircleList* sList = (TCircleList*)list;
	int ret = (sList != NULL) && (node != NULL) && (pos >= 0);
	int i;
	
	if(ret)
	{
		CircleListNode* current = (CircleListNode*)sList;
		for(i=0; (i< pos) && (current->next != NULL); i++)
		{
			current = current->next;
		}
		node->next = current->next;
		current->next = node;
		
		if(sList->length == 0)
		{
			sList->slider = node;
			node->next = node;
		}
		
		sList->length++;
	}
	return ret;
}

CircleListNode* CircleList_Get(CircleList* list, int pos)
{
	TCircleList* sList = (TCircleList*)list;
	CircleListNode* ret = NULL;
	int i = 0;
	
	if((sList!=NULL) && (0<= pos))
	{
		CircleListNode* current = (CircleListNode*)sList;
		
		for(i = 0;i< pos; i++)
		{
			current = current->next;
		}
		ret = current->next;
	}
	return ret;
}

CircleListNode* CircleList_Delete(CircleList* list, int pos)
{
	TCircleList* sList = (TCircleList*)list;
	CircleListNode* ret = NULL;
	int i = 0;
	
	if((sList!=NULL) && (0<= pos) && (pos < sList->length))
	{
		CircleListNode* current = (CircleListNode*)sList;
		CircleListNode* first = sList->header.next;
		CircleListNode* last = (CircleListNode*)CircleList_Get(sList,sList->length-1);
		
		for(i = 0;i< pos; i++)
		{
			current = current->next;
		}
		ret = current->next;
		current->next = ret->next;
		sList->length--;
		if(first == ret)
		{
			sList->header.next = ret->next;
			last->next = ret->next;
		}
		
		if(sList->slider == ret)
		{
			sList->slider = ret->next;
		}
		
		if(sList->length == 0)
		{
			sList->header.next = NULL;
			sList->slider = NULL;
		}
	}
	return ret;
}

CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node)
{
	TCircleList* sList = (TCircleList*)list;
	CircleListNode* ret = NULL;
	int i = 0;
	
	if(sList != NULL)
	{
		CircleListNode* current = (CircleListNode*)sList;
		
		for(i = 0; i<sList->length;i++)
		{
			if(current->next == node)
			{
				ret = current->next;
				break;
			}
			current = current->next;
		}
		if(ret != NULL)
		{
			CircleList_Delete(sList,i);
		}
	}
	return ret;
}

CircleListNode* CircleList_Reset(CircleList* list)
{
	TCircleList* sList = (TCircleList*)list;
	CircleListNode* ret = NULL;
	
	if(sList!= NULL)
	{
		sList->slider = sList->header.next;
		ret = sList->slider;
	}
	return ret;
}

CircleListNode* CircleList_Current(CircleList* list)
{
	TCircleList* sList = (TCircleList*)list;
	CircleListNode* ret = NULL;
	
	if(sList !=NULL)
	{
		ret = sList->slider;
	} 
	return ret;
}

CircleListNode* CircleList_Next(CircleList* list)
{
	TCircleList* sList = (TCircleList*)list;
	CircleListNode* ret = NULL;
	
	if((sList != NULL) && (sList->slider != NULL))
	{
		ret = sList->slider;
		sList->slider = ret->next;
	}
	return ret;
}
#include 
#include 
#include "CircleList.h"

/* run this program using the console pauser or add your own getch, system("pause") or input loop */


struct Value
	{
		CircleListNode header;
		int v;
	};

int main(int argc, char *argv[]) {
	int i = 0;
	CircleList* list = CircleList_Create();
	
	struct Value v1;
	struct Value v2;
	struct Value v3;
	struct Value v4;
	struct Value v5;
	struct Value v6;
	struct Value v7;
	struct Value v8;
	
	v1.v = 1; 
	v2.v = 2;
	v3.v = 3;
	v4.v = 4;
	v5.v = 5;
	v6.v = 6;
	v7.v = 7;
	v8.v = 8;
	
	CircleList_Insert(list,(CircleListNode*)&v1,CircleList_Length(list));
	CircleList_Insert(list,(CircleListNode*)&v2,CircleList_Length(list));
	CircleList_Insert(list,(CircleListNode*)&v3,CircleList_Length(list));
	CircleList_Insert(list,(CircleListNode*)&v4,CircleList_Length(list));
	
	CircleList_Insert(list,(CircleListNode*)&v5,5);
	
	for(i = 0; i< CircleList_Length(list);i++)
	{
		struct Value* pv = (struct Value*)CircleList_Get(list,i);
		
		printf("%d\n",pv->v);
	}
	
	printf("\n");
	
	while(CircleList_Length(list) > 0)
	{
		struct Value* pv = (struct Value*)CircleList_Delete(list,0);
		
		printf("%d\n",pv->v);
	}
	
	CircleList_Insert(list,(CircleListNode*)&v1,CircleList_Length(list));
	CircleList_Insert(list,(CircleListNode*)&v2,CircleList_Length(list));
	CircleList_Insert(list,(CircleListNode*)&v3,CircleList_Length(list));
	CircleList_Insert(list,(CircleListNode*)&v4,CircleList_Length(list));
	CircleList_Insert(list,(CircleListNode*)&v5,CircleList_Length(list));
	CircleList_Insert(list,(CircleListNode*)&v6,CircleList_Length(list));
	CircleList_Insert(list,(CircleListNode*)&v7,CircleList_Length(list));
	CircleList_Insert(list,(CircleListNode*)&v8,CircleList_Length(list));
	
	for(i = 0; i< CircleList_Length(list);i++)
	{
		struct Value* pv = (struct Value*)CircleList_Next(list);
		
		printf("%d\n",pv->v);
	}
	
	printf("\n");
	
	CircleList_Reset(list);
	
	while(CircleList_Length(list) > 0)
	{
		struct Value* pv = NULL;
		
		for(i=0;i< 3;i++)
		{
			CircleList_Next(list);
		}
		pv = (struct Value*)CircleList_Current(list);
		
		printf("%d\n",pv->v);
		
		CircleList_DeleteNode(list,(CircleListNode*)pv);
	}
	CircleList_Destroy(list);
	return 0;
}

小结

  1. 循环链表只是在单链表的基础上做了一个加强
  2. 循环链表可以完全取代单链表的使用
  3. 循环链表的next和current操作可以高效的遍历链表中的所有元素

你可能感兴趣的:(链表,指针,单链表,数据结构,算法)