2020-08-06

双链表

#ifndef _DS_H_
#define _DS_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Windows.h>
#include <math.h>
#include <time.h>
#include <assert.h>
#include <stdbool.h>
#include <iostream>
#define _CRT_SECURE_NO_WARNINGS
typedef int ElemType;



#endif // !_DS_H所有变量声明
#include "DS.h"


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

typedef DCListNode* DCList;
typedef int ElemType;

void Menu()
{
	printf("****************************************************************\n");
	printf("** 1、尾插(push_back)               2、头插(push_front)       **\n");
	printf("** 3、打印单链表(show_Slist)        4、尾删(pop_back)         **\n");
	printf("** 5、头删(pop_front)               6、单链表长度(length)     **\n");
	printf("** 7、查找(find)                    8、按值删除(erase_val)    **\n");
	printf("** 9、排序(升)(sort)                0、退出(exit)             **\n");
	printf("** 10、按值插入(insert_val)         11、头元素(front)         **\n");
	printf("** 12、尾元素(back)                 13、删除(erase_all)       **\n");
	printf("** 14、清除(clear)                  15、转置(reverse)         **\n");
	printf("****************************************************************\n");
	printf("请选择:>");
}

DCListNode* _Buynode(ElemType v = ElemType())
{
	DCListNode* _S = (DCListNode*)malloc(sizeof(DCListNode));
	assert(_S != NULL);
	_S->data = v;
	_S->next = _S->prev = _S;
	return _S;
}
void DCListInit(DCList *phead)//初始化
{
	//DCListNode *s = (DCListNode*)malloc(sizeof(DCListNode));
	//assert(s != NULL);
	//s->next = s->prev = s;

	*phead = _Buynode();
}


void DCListPushBack(DCList* phead, ElemType x)
{
	assert(phead != NULL);
	DCListNode* s = _Buynode(x);
	DCListNode* head = *phead;

	//链接结点
	s->prev = head->prev;
	s->next = head;
	head->prev->next = s;//s->prev->next = s
	head->prev = s;
	
}

void DCListShow(DCList phead)
{
//	assert(phead != NULL);
	DCListNode* p = phead->next;
	while (p != phead)
	{
		printf("%d->", p->data);
		p = p->next;
	}
	printf("双链表打印完成.\n");
}

void DCListPushFront(DCList* phead, ElemType x)
{
	assert(phead != NULL);
	DCListNode* s = _Buynode(x);
	DCListNode* head = *phead;
	assert(s != NULL);

	//链接结点
	s->next = head->next;
	s->prev = head;
	s->prev->next = s;      // head->next->prev = s;
	s->next->prev = s;      // head->next = s;
}

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

void DCListPopBack(DCList* phead)
{
	assert(phead != NULL);
	DCListNode* head = *phead;

	DCListNode* p = head->prev;
	//if (head->next == head)
	//{
	//	return;
	//}
	//p->prev->next = head;
	//head->prev = p->prev;
	//free(p);

	if (p != head->next)
	{
		head->prev = head->prev->prev;
		head->prev->next = head;
		free(p);
	}
	else
	{
		return;
	}
}

void DCListPopFront(DCList* phead)
{
	assert(phead != NULL);
	DCListNode* head = *phead;
	if (head->next == head)
	{
		return;
	}

	DCListNode* p = head->next;
	p->next->prev = p->prev;
	p->prev->next = p->next;
	free(p);
}

DCListNode* DCListFind(DCList phead, ElemType key)
{
	assert(phead != NULL);
	DCListNode* p = phead->next;

	while (p != phead && key != p->data)
	{
		p = p->next;
	}
	if (p == phead)
	{
		p = NULL;
	}
	return p;
}

void DCListEraseByVal(DCList *phead, ElemType del)
{
	assert(phead != NULL);
	DCListNode* p = DCListFind(*phead, del);
	if (p == NULL)
	{
		printf("删除失败......\n");
		return;
	}
	
	if (p->next == *phead)//删除末尾结点
	{
		DCListPopBack(phead);
		printf("删除成功......\n");
	}
	else if(p->next != *phead)
	{
		DCListNode* q = p->next;
		p->data = q->data;
		p->next = q->next;
		p->prev = q->prev;
		free(q);
		printf("删除成功......\n");
	}

//	code2
//	//assert(phead != NULL);
//	//SListNode* p = SListFind(*phead, del);
//	//if (p == NULL)
//	//{
//	//	printf("删除失败......\n");
//	//	return;
//	//}
//
//	//SListNode* prev = *phead;
//	//while (prev != p && prev->next != p)
//	//{
//	//	prev = prev->next;
//	//}
//	//if (prev == p)
//	//{
//	//	*phead = p->next;
//	//}
//	//else
//	//{
//	//	prev->next = p->next;
//	//}
//	//free(p);
}

void DCListSortAsc(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* temp = phead->next;
		while (temp != phead && p->data > temp->data)
		{
			temp = temp->next;
		}
		p->next = temp;
		p->prev = temp->prev;
		p->next->prev = p;
		p->prev->next = p;
	}
}

void DCListInsertByVal(DCList phead, ElemType key)
{
	assert(phead != NULL);
	DCListNode* p = phead->next;
	while (p != phead && key > p->data)
	{
		p = p->next;
	}
	DCListNode* s = _Buynode(key);
	s->next = p;
	s->prev = p->prev;
	s->prev->next = s;
	s->next->prev = s;
}

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;
}

//删除单链表中所有指定元素
void DCListEraseAll(DCList phead, ElemType x) //*phead -> SListNode*
{
	assert(phead != NULL);
	DCListNode* p;
	DCListNode* r;
	p = phead;

	while (p->next)
	{
		if (p->next->data == x)
		{
			r = p->next;
			p->next = p->next->next;
			delete r;
		}
		else
		{
			p = p->next;
		}
	}
}

void DCListClear(DCList *phead)
{
	assert(phead != NULL);
	DCListNode* head = *phead;
	if (head->next == head)
	{
		return;
	}
	DCListNode* p = head->next;
	while (p != head)
	{
		p->prev->next = p->next;
		p->next->prev = p->prev;
		free(p);
		p = head->next;//p的更新
	}
}

void DCListDestroy(DCList* phead)//摧毁单链表
{
	DCListClear(phead);//清空
	free(*phead);
	*phead = NULL;//预防野指针
}

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;
	}
}






int main()
{
	DCList list;
	DCListInit(&list);

	DCListNode* p = NULL;
	ElemType item;
	int select = 0;
	Menu();
	(void)scanf("%d", &select);
	do
	{
		switch (select)
		{
		case 1:
			printf("尾部插入......\n");
			printf("请输入要插入的数据<-1结束>:");
			while ((void)scanf("%d", &item),item != -1)
			{
				DCListPushBack(&list, item);
			}
			printf("尾部插入成功......\n");
			break;

		case 2:
			printf("头部插入......\n");
			printf("请输入要插入的数据<-1结束>:");
			while ((void)scanf("%d", &item),item != -1)
			{
				DCListPushFront(&list, item);
			}
			printf("头部插入成功......\n");
			break;

		case 3:
			printf("打印双链表......\n");
			DCListShow(list);
			printf("打印双链表完成......\n");
			break;

		case 4:
			printf("尾删......\n");
			DCListPopBack(&list);
			printf("尾部删除完成......\n");
			break;

		case 5:
			printf("头删......\n");
			DCListPopFront(&list);
			printf("头部删除完成......\n");
			break;

		case 6:
			printf("双链表长度......\n");
			printf("Length = %d\n", DCListLength(list));
			printf("长度打印完成\n");
			break;

		case 7:
			printf("查找......\n");
			printf("请输入要查找的值:>");
			(void)scanf("%d", &item);
			p = DCListFind(list, item);
			if (p == NULL)
			{
				printf("数据查找失败\n");
			}
			else
			{
				printf("数据查找成功\n");
			}
			break;

		case 8:
			printf("按值删除......\n请输入要删除的值:>");
			(void)scanf("%d", &item);
			DCListEraseByVal(&list, item);
			break;

		case 9:
			printf("升序排序......\n");
			DCListSortAsc(list);
			printf("排序完成......\n");
			break;


		case 10:
			printf("按值插入......\n");
			printf("请输入要插入的值:>");
			(void)scanf("%d", &item);
			DCListSortAsc(list);
			DCListInsertByVal(list, item);
			printf("按值插入完成......\n");
			break;

		case 11:
			printf("链表头元素 = %d\n", DCListFront(list));
			printf("头部元素打印完成......\n");
			break;

		case 12:
			printf("链表尾元素 = %d\n", DCListBack(list));
			printf("尾部元素打印完成......\n");
			break;

		case 13:
			printf("请输入要删除的元素:>");
			(void)scanf("%d", &item);
			DCListEraseAll(list, item);
			printf("删除完成......\n");
			break;

		case 14:
			printf("清空链表......\n");
			DCListClear(&list);
			printf("清空完成......\n");
			break;

		case 15:
			printf("转置单链表......\n");
			DCListReverse(list);
			printf("转置完成......\n");
			break;

		case 0:
			printf("退出!!!");
			break;

		default:
			printf("输入有误,请重新输入!!!");
			break;
		}
		printf("\n");
		Menu();
		(void)scanf("%d", &select);
	} while (select);

	printf("单链表摧毁开始......\n");
	for (int i = 10; i >= 0; i--)
	{
		printf("%d......\n", i);
		Sleep(1000);
	}
	DCListDestroy(&list);
	printf("双链表摧毁成功\n");
	return EXIT_SUCCESS;
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

枳洛淮南✘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值