温故而知新->数据结构->带头双向循环链表->程序实现2_利用类

带头双向循环链表 ~ 程序实现二

本篇博客基于 温故而知新 -> 数据结构 -> 线性表 -> 链表 中的理论知识,并利用 C++ 中的 对数据结构中的 带头双向循环链表 进行代码实现!

其中涉及了链表的 (头插、尾插、任插)(头删、尾删、任删)(节点寻找)改(没写(~ ̄▽ ̄)~),销毁,打印等操作!并附带了实例以及对应的运行结果!

具体内容如下:
(1)DList.h

#pragma once
#include<iostream>
using namespace std;
#include<assert.h>

typedef int DLTDataType;
// 双向节点
typedef struct DLTNode
{
	DLTDataType _val;
	struct DLTNode *_prev;
	DLTNode *_next;
};

DLTNode *createNode(DLTDataType val)
{
	DLTNode *node = (DLTNode*)malloc(sizeof(DLTNode));
	node->_next = node->_prev = NULL;
	node->_val = val;
	return node;
}

// 双向链表
class DList
{
public:
	DList()
	{
		_head = (DLTNode*)malloc(sizeof(DLTNode));
		_head->_next = _head->_prev = _head;
	}
	~DList()
	{
		if(_head != NULL)
		{
			free(_head);
			_head = NULL;
		}
	}

	// 双向链表打印
	void Print();
	// 单节点打印
	void NodePrint(DLTNode *node);
	// 双向链表尾插
	void PushBack(DLTDataType val);
	// 双向链表尾删
	void PopBack();
	// 双向链表头插
	void PushFront(DLTDataType val);
	// 双向链表头删
	void PopFront();

	// 双向链表查找
	DLTNode* Find(DLTDataType val);
	// 双向链表在pos的前面进行插入
	void Insert(DLTNode* pos, DLTDataType val);
	// 双向链表删除pos位置的节点
	void Erase(DLTNode* pos);
	// 双向链表销毁
	void Destory();

private:
	DLTNode *_head;
};

(2)main.c

#include"DList.h"

// 双向链表打印
void DList::Print()
{
	assert(_head->_next != _head);
	DLTNode *cur = _head->_next;
	cout << "链表内容:";
	while (cur != _head)
	{
		cout << cur->_val << " ";
		cur = cur->_next;
	}cout << endl;
}
// 单节点打印
void DList::NodePrint(DLTNode *node)
{
	cout << "该节点数据为:" << node->_val << endl;
}
// 双向链表尾插
void DList::PushBack(DLTDataType val)
{
	DLTNode *newNode = createNode(val);
	/* 方法一:正向找出最后一个节点 --- 太麻烦,建议用方法二*/
	/*DLTNode *cur = _head->_next;
	while (cur->_next != _head)
		cur = cur->_next;
	cur->_next = newNode;
	newNode->_prev = cur;
	newNode->_next = _head;
	_head->_prev = newNode;*/

	/* 方法二:逆向找出最后一个节点,即最后一个节点为 _head->_prev */
	DLTNode *end = _head->_prev;
	end->_next = newNode;
	newNode->_prev = end;

	_head->_prev = newNode;
	newNode->_next = _head;
}
// 双向链表尾删
void DList::PopBack()
{
	assert(_head->_next != _head);
	DLTNode *end = _head->_prev;
	_head->_prev = end->_prev;
	end->_prev->_next = _head;
	free(end);
}
// 双向链表头插
void DList::PushFront(DLTDataType val)
{
	DLTNode *newNode = createNode(val);
	DLTNode *next = _head->_next;
	_head->_next = newNode;
	newNode->_prev = _head;

	newNode->_next = next;
	next->_prev = newNode;
}
// 双向链表头删
void DList::PopFront()
{
	assert(_head->_next != _head);
	DLTNode *next = _head->_next;
	_head->_next = next->_next;
	next->_next->_prev = _head;
	free(next);
}

// 双向链表查找 -- 默认正向查找
DLTNode* DList::Find(DLTDataType val)
{
	assert(_head->_next != _head);
	DLTNode *node = _head;
	while (node->_next != _head)
	{
		if (node->_val == val)
			return node;
		node = node->_next;
	}
	return NULL;
}
// 双向链表在pos的前面进行插入
void DList::Insert(DLTNode* pos, DLTDataType val)
{
	assert(_head->_next != _head || pos != NULL || pos != pos->_next);
	DLTNode *newNode = createNode(val);
	DLTNode *prev = pos->_prev;
	prev->_next = newNode;
	newNode->_prev = prev;

	newNode->_next = pos;
	pos->_prev = newNode;
}
// 双向链表删除pos位置的节点
void DList::Erase(DLTNode* pos)
{
	assert(_head->_next != _head || pos != NULL || pos != pos->_next);
	DLTNode *prev = pos->_prev;
	DLTNode *next = pos->_next;
	prev->_next = next;
	next->_prev = prev;
	free(pos);
}
// 双向链表销毁
void DList::Destory()
{
	DLTNode *cur = _head->_next;
	while (cur != _head)
	{
		DLTNode *next = cur->_next;
		free(cur);
		cur = next;
	}
	free(_head);
	_head = NULL;
	cout << "销毁结束" << endl;
}

void test()
{
	DList l1;
	/* 实验尾插 */
	l1.PushBack(1);
	l1.PushBack(2);
	l1.PushBack(3);
	l1.PushBack(4);
	l1.Print(); // 1 2 3 4

	/* 实验尾删 */
	l1.PopBack();
	l1.Print(); // 1 2 3
	l1.PopBack();
	l1.Print(); // 1 2
	l1.PopBack();
	l1.Print(); // 1
	//l1.PopBack();
	//l1.Print(); // 此时会警告,因为 assert()
	
	/* 实验头插 */
	l1.PushFront(2);
	l1.PushFront(3);
	l1.PushFront(4);
	l1.Print(); // 4 3 2 1

	/* 实验头删 */
	l1.PopFront();
	l1.Print(); // 3 2 1
	//l1.PopFront();
	//l1.Print(); // 2 1
	//l1.PopFront();
	//l1.Print(); // 1
	l1.PopFront();
	l1.Print(); // 此时会警告,因为 assert()

	/* 实验find */
	DLTNode *node = l1.Find(2);
	l1.NodePrint(node);

	/* 实验任插 */
	l1.Insert(node, 222);
	l1.Print();// 3 222 2 1
	l1.Insert(node, 555);
	l1.Print();// 3 222 555 2 1

	/* 实验任删 */
	l1.Erase(node);
	l1.Print();// 3 222 555 1

	l1.Destory();
}

int main()
{
	test();
	system("pause");
	return 0;
}

(3)运行结果
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值