数据结构——双向循环链表

双向循环链表是一种链式存储结构,它的最后一个结点指向头结点,形成一个环。因此,从循环链表中的任何一个结点出发都能找到任何其他结点。双向循环链表的操作和双向链表的操作基本一致,差别仅仅在于算法中的循环条件有所不同。双向循环链表的头结点的前驱指向最后一个结点,尾结点的后继指向头结点。

注意:双向循环链表中无其他结点,只有头结点时 ,头结点的前驱和后继度指向自身。

1、双向循环链表的存储结构

typedef int ElemType;

typedef struct CycNode
{
	struct CycNode *prev;
	ElemType data;
	struct CycNode *next;
}CycNode;


typedef struct CycDouList
{
	CycNode *head;
	int count;
}CycDouList, *pCycDouList;

 

2、双向循环链表的初始化

void InitCycDouList(pCycDouList list)		//初始化函数
{
	assert(list != NULL);
	list->head = NULL;
	list->count = 0;
}

3、双向循环链表的扩充

static CycNode *BuyNode(ElemType value, CycNode *prev, CycNode* next)
{
	CycNode * s = (CycNode *)malloc(sizeof(CycNode));
	assert(s != NULL);

	s->data = value;

	if (prev == NULL || next == NULL)
	{
		s->next = s->prev = s;
	}
	else
	{
		s->next = next;
		s->prev = prev;
	}

	return s;
}

4、双向循环链表的插入

static void Insert(ElemType value, pCycDouList list, CycNode* p)
{
	CycNode *s = BuyNode(value, p, p->next);

	p->next->prev = s;
	p->next = s;

	list->count++;
}

void InsertCycDouList(pCycDouList list, ElemType value, int pos)		//插入函数
{
	assert(list != NULL);

	if (list->head == NULL)
	{
		CycNode *s = BuyNode(value, NULL, NULL);
		list->head = s;
		list->count++;
		return;
	}

	if (pos < 0 || pos > list->count)
	{
		printf("insert pos is error\n");
		return;
	}

	CycNode *p = list->head;

	if (pos == 0)
	{
		p = p->prev;
		Insert(value, list, p);
		list->head = list->head->prev;
	}
	else
	{
		while (pos > 1)
		{
			p = p->next;
			pos--;
		}

		Insert(value, list, p);
	}
}

5、双向循环链表的删除


void DeleteCycDouList(pCycDouList list, int pos)		//删除函数
{
	assert(list != NULL);

	if (pos < 1 || pos > list->count)
	{
		printf("delete pos is error\n");
		return;
	}

	if (list->head->next == list->head)
	{
		free(list->head);
		list->head = NULL;
		list->count--;
		return;
	}

	CycNode *p = list->head;

	if (pos == 1)
	{
		while (p->next != list->head)
		{
			p = p->next;
		}

		list->head = list->head->next;
	}
	else
	{
		while (pos > 2)
		{
			p = p->next;
			pos--;
		}
	}

	CycNode *q = p->next;
	p->next = q->next;

	free(q);
	list->count--;
}

6、双向循环链表的打印

void ShowCycDouList(pCycDouList list)		//打印函数及链表的长度
{
	assert(list != NULL);
	if (list->head == NULL)
	{
		printf("list is empty\n");
		return;
	}


	CycNode *p = list->head;

	while (p->next != list->head)
	{
		printf("%d  ", p->data);
		p = p->next;
	}

	printf("%d  \n", p->data);
	printf("len = %d\n", list->count);
}

7、双向循环链表的查找

void FindCycDouList(pCycDouList list,int n)			//查找函数
{
	assert(list != NULL);
	if (n < 0 || n > list->count)
	{
		printf("count is error\n");
		return;
	}

	CycNode *p = list->head;

	for (int i = 1; i < n; i++)
	{
		p = p->next;
	}
	printf("%d\n",p->data);
}

猜你喜欢

转载自blog.csdn.net/wry_sunny_/article/details/88575778