数据结构——带头结点的双链表增删查改的C语言实现

1、dclist.h

#ifndef _dclist_h_
#define _dclist_h_

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
#include<memory.h>
#include<vld.h>  
#pragma warning(disable:4996)
#define ElemType int
typedef struct DCListNode
{
	ElemType data;
	struct DCListNode *next;
	struct DCListNode *prev;
}DCListNode;
typedef DCListNode *DCList;

void DCListInit(DCList *phead);
void DCListPushBack(DCList *phead, ElemType x);
void DCListPushFront(DCList *phead, ElemType x);
void DCListShow(DCList phead);
void DCListPopBack(DCList *phead);
void DCListPopFront(DCList *phead);
bool DCListInsertVal(DCList phead, ElemType x);
void DCListEraseVal(DCList phead, ElemType x);
DCListNode* DCListFind(DCList phead, ElemType x);
size_t DCListLength(DCList phead);
void DCListSort(DCList phead);
void DCListReverse(DCList phead);
void DCListClear(DCList *phead);
ElemType DCListFront(DCList phead);
ElemType DCListBack(DCList phead);
void DCListDestroy(DCList *phead);
#endif

(1)初始化

DCListNode* _Buynode()
{
	DCListNode *_S = (DCListNode*)malloc(sizeof(DCListNode));
	assert(_S != NULL);
	_S->next = _S->prev = _S;
	return _S;
}
void DCListInit(DCList *phead)
{
	assert(phead != NULL);
	*phead = _Buynode();
}

(2) 尾插、头插

void DCListPushBack(DCList *phead, ElemType x)
{
	assert(phead != NULL);
	DCListNode *s = (DCListNode *)malloc(sizeof(DCListNode));
	DCListNode *p = *phead;
	assert(s != NULL);
	s->data = x;
	s->prev = p->prev;
	s->next = p;
	p->prev->next = s;
	p->prev = s;
}
void DCListPushFront(DCList *phead, ElemType x)
{
	assert(phead != NULL);
	DCListNode *s = (DCListNode *)malloc(sizeof(DCListNode));
	DCListNode *p = *phead;
	assert(s != NULL);
	s->data = x;
	s->prev = p;
	s->next = p->next;
	s->prev->next = s;
	s->prev->next = s;
}

(3)链表打印

void DCListShow(DCList phead)
{
	assert(phead != NULL);
	DCListNode *p = phead->next;
	while (p != phead)
	{
		printf("%d->", p->data);
		p = p->next;
	}
	printf("Over.\n");
}

 (4)尾删、头删

void DCListPopBack(DCList *phead)
{
	assert(phead != NULL);
	DCListNode *p = *phead;
	if (p->next == p)
	{
		printf("链表已空,删除失败!\n");
		return;
	}
	DCListNode *s = p->prev;
	s->prev->next = p;
	p->prev = s->prev;
	free(s);
}
void DCListPopFront(DCList *phead)
{
	assert(phead != NULL);
	DCListNode *p = *phead;
	if (p->next == p)
	{
		printf("链表已空,删除失败!\n");
		return;
	}
	DCListNode *s = p->next;
	s->next->prev = p;
	s->prev->next = s->next;
	free(s);
}

(5)按值插入、删除

bool DCListInsertVal(DCList phead, ElemType x)
{
	assert(phead != NULL);
	DCListNode *p = phead->next;
	while (p != phead && x > p->data)
		p = p->next;
	DCListNode* s = (DCListNode*)malloc(sizeof(DCListNode));
	assert(s != NULL);
	s->data = x;
	s->prev = p->prev;
	s->next = p;
	s->prev->next = s;
	s->next->prev = s;
}
void DCListEraseVal(DCList phead, ElemType x)
{
	assert(phead != NULL);
	DCListNode *p = DCListFind(phead, x);
	if (p == NULL)
		return;
	p->prev->prev = p->next;
	p->next->prev = p->prev;
	free(p);
}

 (6)查找

DCListNode* DCListFind(DCList phead, ElemType x)
{
	assert(phead != NULL);
	DCListNode *p = phead->next;
	while (p != phead && p->data != x)
		p = p->next;
	if (p == phead)
		return;
	return p;
}

(7)求长度

size_t DCListLength(DCList phead)
{
	assert(phead != NULL);
	DCListNode *p = phead->next;
	size_t len = 0;
	while (p != phead)
	{
		len++;
		p = p->next;
	}
	return len;
}

 (8)排序

void DCListSort(DCList phead)
{
	assert(phead != NULL);
	if (DCListLength(phead) == 1)
	{
		return;
	}
	DCListNode *p = phead->next;
	DCListNode *q = p->next;
	p->next = phead;
	phead->prev = p;
	while (q != phead)
	{
		p = q;
		q = q->next;
		DCListNode *tmp = phead->next;
		while (tmp != phead && p->data > tmp->data)
			tmp = tmp->next;
		p->next = tmp;
		p->prev = tmp->prev;
		p->next->prev = p;
		p->prev->next = p;
	}
}

(9)逆置

void DCListReverse(DCList phead)
{
	assert(phead != NULL);
	if (DCListLength(phead) == 1)
	{
		return;
	}
	DCListNode *p = phead->next;
	DCListNode *q = p->next;
	p->next = phead;
	phead->prev = p;
	while (q != phead)
	{
		p = q;
		q = q->next;
		p->next = phead->next;
		p->prev = phead;
		p->next->prev = p;
		p->prev->next = p;
	}
}

(10)清空

void DCListClear(DCList *phead)
{
	assert(phead != NULL);
	DCListNode *p = (*phead)->next;
	while (p != *phead)
	{
		p->prev->next = p->next;
		p->next->prev = p->prev;
		free(p);
		p = (*phead)->next;
	}
}

(11)取头元素、尾元素

ElemType DCListFront(DCList phead)
{
	assert(phead != NULL);
	assert(phead->next != phead);
	return phead->next->data;
}
ElemType DCListBack(DCList phead)
{
	assert(phead != NULL);
	assert(phead->next != phead);
	return phead->prev->data;
}

(12)摧毁

void DCListDestroy(DCList *phead)
{
	assert(phead != NULL);
	DCListClear(phead);
	free(*phead);
	*phead = NULL;
}

2、dclist.c

#include"dclist.h"

int main()
{
	DCList list;
	DCListInit(&list);
	DCListNode *p = NULL;
	ElemType item;
	int pos;
	bool flag;
	int select = 1;
	while (select)
	{
		printf("***************************************\n");
		printf("* [1] push_back       [2] push_front  *\n");
		printf("* [3] show_list       [0] quit_system *\n");
		printf("* [4] pop_back        [5] pop_front   *\n");
		printf("* [6] insert_val      [7] erase_val   *\n");
		printf("* [8] find            [9] length      *\n");
		printf("* [10] sort           [11] reverse    *\n");
		printf("* [12] clear          [13] front      *\n");
		printf("* [14] back           [15] destroy    *\n");
		printf("***************************************\n");
		printf("请选择:>");
		scanf("%d", &select);
		if (select == 0)
		{
			break;
		}
		switch (select)
		{
		case 1:
			printf("请输入要插入的数据<以-1结束>:");
			while (scanf("%d", &item), item != -1)
			{
				DCListPushBack(&list, item);
			}
			printf("尾部插入数据成功!\n");
			break;
		case 2:
			printf("请输入要插入的数据<以-1结束>:");
			while (scanf("%d", &item), item != -1)
			{
				DCListPushFront(&list, item);
			}
			printf("头部插入数据成功!\n");
			break;
		case 3:
			DCListShow(list);
			break;
		case 4:
			DCListPopBack(&list);
			printf("尾部删除数据成功!\n");
			break;
		case 5:
			DCListPopFront(&list);
			printf("头部删除数据成功!\n");
			break;
		case 6:
			printf("请输入要插入的元素:");
			scanf("%d", &item);
			DCListSort(&list);
			DCListInsertVal(list, item);
			flag = DCListInsertVal(&list, item);
			if (flag)
			{
				printf("插入数据成功!\n");
			}
			else
			{
				printf("插入数据失败!\n");
			}
			break;
		case 7:
			printf("请输入要删除的元素:");
			scanf("%d", &item);
			DCListEraseVal(list, item);
			printf("删除元素成功!\n");
			break;
		case 8:
			printf("请输入要查找的元素:");
			scanf("%d", &item);
			DCListFind(list, item);
			break;
		case 9:
			printf("SeqList length=%d\n", DCListLength(list));
			break;
		case 10:
			DCListSort(list);
			printf("顺序表排序成功!\n");
			break;
		case 11:
			DCListReverse(list);
			printf("顺序表转置完成!\n");
			break;
		case 12:
			DCListClear(&list);
			break;
		case 13:
			printf("表头元素为%d\n", DCListFront(list));
			break;
		case 14:
			printf("表尾元素为%d\n", DCListBack(list));
			break;
		case 15:
			DCListDestroy(&list);
			printf("摧毁成功!\n");
			break;
		default:
			printf("输入错误,请重新选择.......\n");
			break;
		}
		system("pause");
		system("cls");
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值