【双向循环带头链表】

双向循环带头链表

 双向循环带头链表结构如下
【双向循环带头链表】_第1张图片
 先设计数据结构如下。
typedef int LTDataType;
typedef struct ListNode
{
struct ListNode* prev;
struct ListNode* next;
LTDataType val;
}LTNode;.
  第一个节点为头结点,后面链接的节点存储数据。一个指向前面的指针prev,一个指向后面的指针next,一个数据。

 实现下面的接口
LTNode* ListInit();
void ListDestory(LTNode* phead);
void ListPrint(LTNode* phead);
void ListPushBack(LTNode* phead, LTDataType data);
void ListPopBack(LTNode* phead);
void ListPushFront(LTNode* phead, LTDataType data);
void ListPopFront(LTNode* phead);
LTNode* ListFind(LTNode* phead, LTDataType data);
// 双向链表在pos的前面进行插入
void ListInsert(LTNode* pos, LTDataType data);
// 双向链表删除pos位置的结点
void ListErase(LTNode* pos);


LTNode* ListInit();这个节点的实现初始化,要注意,两个指针要自己指向自己,在写后面的接口中有大用.

LTNode* BuyNode(LTDataType data)
{
	LTNode* node = (LTNode*)malloc(sizeof(LTNode));
	if (node == NULL)
	{
		perror("malloc fail");
		return;
	}
	node->prev = node;
	node->next = node;
	node->val = data;
	return node;
}

LTNode* ListInit()
{
	LTNode* node = (LTNode*)malloc(sizeof(LTNode));
	if (node == NULL)
	{
		perror("malloc fail");
		return;
	}
	node->prev = node->next = node;
	return node;
}
}

 ListDestory接口实现定义一个指针cur = phead->next,先保存下一个节点的地址,在free.

void ListDestory(LTNode* phead)
{
	assert(phead);
	LTNode* cur = phead->next;
	while (cur!=phead)
	{
		LTNode* next = cur->next;
		free(cur);
		cur = next;
	}
	free(phead);
	phead = NULL;
}

 ListPrint,遍历直接·打印

void ListPrint(LTNode* phead)
{
	assert(phead);
	LTNode* cur = phead->next;
	while (cur!=phead)
	{
		printf("%d->", cur->val);
		cur = cur->next;
	}
	printf("\n---------------------------\n");
}

 LIstPushBack直接尾插,

void ListPushBack(LTNode* phead, LTDataType data)
{
	assert(phead);
	LTNode* newnode = BuyNode(data);
	LTNode* tail = phead->next;
	while (phead != tail->next)找到尾直接插入
	{
		tail = tail->next;
	}
	LTNode* prev = tail;
	LTNode* next = tail->next;

	prev->next = newnode;
	newnode->prev = prev;

	newnode->next = next;
	next->prev = newnode;
}

 尾删

void ListPopBack(LTNode* phead)
{
	assert(phead);
	if (phead->next == phead)
	{
		printf("No node\n");
		return;
	}
	LTNode* cur = phead->next;
	while (cur->next != phead)
	{
		cur = cur->next;
	}
	LTNode* prev = cur->prev;
	LTNode* next = cur->next;
	free(cur);
	prev->next = next;
	next->prev = prev;
}

 头插

void ListPushFront(LTNode* phead, LTDataType data)
{
	assert(phead);
	LTNode* newnode = BuyNode(data);
	LTNode* next = phead->next;

	phead->next = newnode;
	newnode->prev = phead;

	newnode->next = next;
	next->prev = newnode;
}

 头删

void ListPopFront(LTNode* phead)
{
	assert(phead);
	if (phead->next == phead)
	{
		printf("No node\n");
		return;
	}
	LTNode* del = phead->next;
	LTNode* next = del->next;
	free(del);
	del = NULL;
	phead->next = next;
	next->prev = phead;

}

 下面接口

LTNode* ListFind(LTNode* phead, LTDataType data)
{
	assert(phead);
	LTNode* cur = phead->next;
	while (cur != phead)
	{
		if (cur->val == data)
		{
			return cur;
		}
		cur = cur->next;
	}
}

// 双向链表在pos的前面进行插入
void ListInsert(LTNode* pos, LTDataType data)
{
	assert(pos);
	LTNode* newnode = BuyNode(data);
	LTNode*  prev = pos->prev;

	prev->next = newnode;
	newnode->prev = prev;

	newnode->next = pos;
	pos->prev = newnode;
	
}
// 双向链表删除pos位置的结点
void ListErase(LTNode* pos)
{
	assert(pos);
	LTNode* prev = pos->prev;
	LTNode* next = pos->next;
	free(pos);
	pos = NULL;
	prev->next = next;
	next->prev = prev;
}

 完结!

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