欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

数据结构:带头节点的双向循环链表的操作

程序员文章站 2024-03-23 14:54:52
...

分为三个部分:test.c,DList.c,DList.h

  • test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "DList.h"
#include <stdio.h>
#include <stdlib.h>
void menu()
{
	printf("**1.尾插             2.尾删            **\n");
	printf("**3.头插             4.头删            **\n");
	printf("**5.任意位置插入     6.任意位置删除    **\n");
	printf("**7.打印             8.销毁            **\n");

}
void test()
{
	int input = 0;
	DLDataType data = 0;
	DLNode *PH = NULL;
	DLDataType val = 0;
	DListInit(&PH);
	do
	{
		menu();
		printf("请选择;>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("请输入要插入的数:");
			scanf("%d", &data);
			DListPushBack(PH, data);
			break;
		case 2:
			DListPopBack(PH);
			break;
		case 3:
			printf("请输入要插入的数:");
			scanf("%d", &data);
			DListPushFront(PH, data);
			break;
		case 4:
			DListPopFront(PH);
			break;
		case 5:
			printf("请输入要插入哪个数前面:");
			scanf("%d", &val);
			printf("请输入要插入的值:");
			scanf("%d", &data);
			DListInsertFront(DListFind(PH, val), data);
			break;
		case 6:
			printf("请输入要删除的数:");
			scanf("%d", &data);
			DListErase(DListFind(PH, data));
			break;
		case 7:
			DListPrint(PH);
			break;
		case 8:
			DListDestroy(&PH);
			break;
		}
	} while (input);
}
int main()
{
	test();
	system("pause");
	return 0;
}
  • DList.h
#pragma once
typedef int DLDataType;
typedef struct DListNode//带头节点双向循环链表
{
	DLDataType _data;
	struct DListNode* _pPre;
	struct DListNode* _pNext;
}DLNode;
void DListInit(DLNode** pHead);//初始化
void DListPushBack(DLNode *pHead,DLDataType data);//尾插
void DListPopBack(DLNode *pHead);//尾删
void DListPushFront(DLNode *pHead, DLDataType data);//头插
void DListPopFront(DLNode *pHead);//头删
DLNode* DListFind(DLNode *pHead,DLDataType data);//查找
void DListInsertFront(DLNode *pos, DLDataType data);//任意位置插入
void DListErase(DLNode *pos);//任意位置删除
void DListPrint(DLNode *pHead);//显示
void DListDestroy(DLNode **pHead);//销毁
  • DList.c
#include "DList.h"
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
DLNode* BuyDlistNode(DLDataType data)
{
	DLNode *pNewNode = NULL;
	pNewNode = (DLNode*)malloc(sizeof(DLNode));
	if (pNewNode == NULL)
	{
		assert(0);
		return NULL;
	}
	pNewNode->_data = data;
	pNewNode->_pPre = NULL;
	pNewNode->_pNext = NULL;
	return pNewNode;
}
void DListInit(DLNode** pHead)//初始化
{
	assert(pHead);
	*pHead = BuyDlistNode(0);
	//前驱和后继都指向自己
	(*pHead)->_pPre = *pHead;
	(*pHead)->_pNext = *pHead;
}
void DListPushBack(DLNode *pHead, DLDataType data)//尾插
{
	DLNode *pNewNode = NULL;
	assert(pHead);
	pNewNode = BuyDlistNode(data);
	//先不要破坏链表结构
	pNewNode->_pPre = pHead->_pPre;
	pNewNode->_pNext = pHead;
	//破坏链表结构
	pHead->_pPre->_pNext = pNewNode;
	pHead->_pPre = pNewNode;
}
void DListPopBack(DLNode *pHead)//尾删
{
	assert(pHead);
	if (pHead == pHead->_pNext)//链表为空
	{
		return;
	}
	else
	{
		DLNode *pDelNode = pHead->_pPre;
		pHead->_pPre = pDelNode->_pPre;
		pDelNode->_pPre->_pNext = pHead;
		free(pDelNode);
	}
}
void DListPushFront(DLNode *pHead, DLDataType data)//头插
{
	DLNode *pNewNode = NULL;
	assert(pHead);
	pNewNode = BuyDlistNode(data);
	pNewNode->_pNext = pHead->_pNext;
	pNewNode->_pPre = pHead;
	pHead->_pNext = pNewNode;
	pNewNode->_pNext->_pPre = pNewNode;
}
void DListPopFront(DLNode *pHead)//头删
{
	DLNode *pDelNode = NULL;
	assert(pHead);
	if (pHead == pHead->_pNext)
	{
		return;
	}
	pDelNode = pHead->_pNext;
	pHead->_pNext = pDelNode->_pNext;
	pDelNode->_pNext->_pPre = pHead;
	free(pDelNode);
}
DLNode* DListFind(DLNode *pHead,DLDataType data)//查找
{
	DLNode *pCur = pHead->_pNext;
	while (pCur != pHead)
	{
		if (pCur->_data == data)
		{
			return pCur;
		}
		pCur = pCur->_pNext;
	}
	return NULL;
}
void DListInsertFront(DLNode *pos, DLDataType data)//任意位置向前插入
{
	DLNode *pNewNode = BuyDlistNode(data);
	if (pos == NULL)
		return;
	pNewNode->_pNext = pos;
	pNewNode->_pPre = pos->_pPre;
	pos->_pPre->_pNext = pNewNode;
	pos->_pPre = pNewNode;
}
void DListErase(DLNode *pos)//任意位置删除
{
	if (pos == NULL)
		return;
	pos->_pPre->_pNext = pos->_pNext;
	pos->_pNext->_pPre = pos->_pPre;
	free(pos);
}
void DListPrint(DLNode *pHead)//显示
{
	DLNode *pCur = NULL;
	assert(pHead);
	pCur = pHead->_pNext;
	while (pCur != pHead)
	{
		printf("%d ", pCur->_data);
		pCur = pCur->_pNext;
	}
	printf("\n");
}
void DListClear(DLNode *pHead)//将有效结点清除
{
	DLNode *pCur = NULL;
	assert(pHead);
	pCur = pHead->_pNext;
	while (pCur != pHead)
	{
		pHead->_pNext = pCur->_pNext;
		free(pCur);
		pCur = pHead->_pNext;
	}
	pHead->_pNext = pHead;
	pHead->_pPre = pHead;
}
void DListDestroy(DLNode **pHead)//销毁,要释放掉二级指针,也会改变指针的方向
{
	assert(pHead);
	DListClear(*pHead);
	free(*pHead);
	*pHead = NULL;
}