【数据结构】双循环链表(c++)

头文件:

#pragma once

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

template<class Type>
class List;

// 结点类
template<class Type>
class NodeList
{
	friend class List<Type>;
public:
	NodeList();
	NodeList(Type d, NodeList<Type> *n = NULL, NodeList<Type> *m = NULL);
private:
	Type data;
	NodeList<Type>* next;
	NodeList<Type>* prio;
};

// 链表类
template<class Type>
class List
{
public:
	List();
	~List();
public:
	void show_list();
	void tail_insert(Type const &x);
	void head_insert(Type const &x);
	void sort();
	void head_delete();
	void tail_delete();
	void val_insert(Type const &x);
	NodeList<Type>* find(Type const &x);
	void val_delete(Type const &x);
	Type length();
	void reverse();
	void clear();
	void destroy();
	void quit_system(Type &x);
protected:
	NodeList<Type>* BuyNode(Type x = Type())
	{
		NodeList<Type>* p = new NodeList<Type>(x);
		assert(p != NULL);
		return p;
	}
private:
	NodeList<Type>* first;
	NodeList<Type>* last;
};

// 结点类的构造函数
template<class Type>
NodeList<Type>::NodeList()
{
	data = Type();
	next = NULL;
	prio = NULL;
}

template<class Type>
NodeList<Type>::NodeList(Type d, NodeList<Type> *n = NULL, NodeList<Type> *m = NULL)
{
	data = d;
	next = n;
	prio = m;
}

// 链表类的构造函数
template<class Type>
List<Type>::List()
{
	first = last = BuyNode();
	first->prio = last;
	last->next = first;
}

// 链表类的析构函数
template<class Type>
List<Type>::~List()
{
	destroy();
}

// 显示
template<class Type>
void List<Type>::show_list()
{
	NodeList<Type> *p = first->next;
	while (p != first)
	{
		cout << p->data << "->";
		p = p->next;
	}
	cout << "NULL" << endl;
}

// 尾插
template<class Type>
void List<Type>::tail_insert(Type const& x)
{
	NodeList<Type> *p = BuyNode(x);
	last->next = p;
	p->prio = last;
	p->next = first;
	first->prio = p;
	last = p;
	first->data++;
}

// 头插
template<class Type>
void List<Type>::head_insert(Type const &x)
{
	NodeList<Type> *p = BuyNode(x);
	if (first->data == 0)
	{
		tail_insert(x);
	}
	else
	{
		p->next = first->next;
		first->next = p;
		p->prio = first;
		p->next->prio = p;
		first->data++;
	}
}

// 排序
template<class Type>
void List<Type>::sort()
{
	if (first->data == 0)
	{
		return;
	}
	if (first->data == 1)
	{
		show_list();
	}
	NodeList<Type> *t = first->next;
	NodeList<Type> *p = t->next;
	NodeList<Type> *q = NULL;
	t->next = first;
	first->prio = t;
	p->prio = NULL;
	last = t;
	first->data = 1;
	while (p != first)
	{
		val_insert(p->data);
		q = p;
		p = p->next;
		delete q;
	}
}

// 头删
template<class Type>
void List<Type>::head_delete()
{
	if (first->data == 0)
	{
		cout << "the list is empty,cannot delete!" << endl;
		return;
	}
	NodeList<Type> *p = first->next;
	if (first->data == 1)
	{
		last = first;
		first->next = last;
		first->prio = last;
	}
	else
	{
		first->next = p->next;
		p->next->prio = first;
	}
	delete p;
	first->data--;
}

// 尾删
template<class Type>
void List<Type>::tail_delete()
{
	if (first->data == 0)
	{
		cout << "the list is empty,cannot delete!" << endl;
		return;
	}
	NodeList<Type> *s = last;
	last = last->prio;
	last->next = first;
	first->prio = last;
	delete s;
	first->data--;
}

// 按值插入
template<class Type>
void List<Type>::val_insert(Type const &x)
{
	if (first->data == 0)
	{
		tail_insert(x);
		return;
	}
	NodeList<Type> *p = first->next;
	NodeList<Type> *s = BuyNode(x);
	while (p->data < x && p->next != first)
	{
		p = p->next;
	}
	if (p->data >= x)
	{
		p->prio->next = s;
		s->prio = p->prio;
		s->next = p;
		p->prio = s;
		first->data++;
	}
	else
	{
		tail_insert(x);
	}
}

// 查找
template<class Type>
NodeList<Type>* List<Type>::find(Type const &x)
{
	NodeList<Type> *s = first->next;
	while (s != first)
	{
		if (s->data == x)
		{
			return s;
		}
		s = s->next;
	}
	return NULL;
}

// 按值删除
template<class Type>
void List<Type>::val_delete(Type const &x)
{
	if (first->data == 0)
	{
		cout << "the list is empty,cannot delete!" << endl;
		return;
	}
	NodeList<Type> *s = find(x);
	if (s == NULL)
	{
		cout << "the number is not exist,can not delete!" << endl;
		return;
	}
	if (s->next != first)
	{
		s->prio->next = s->next;
		s->next->prio = s->prio;
		first->data--;
		delete s;
	}
	else
	{
		tail_delete();
	}
}

// 求长度
template<class Type>
Type List<Type>::length()
{
	return first->data;
}

// 反转
template<class Type>
void List<Type>::reverse()
{
	if (first->data == 0)
	{
		return;
	}
	if (first->data == 1)
	{
		show_list();
	}
	NodeList<Type> *t = first->next;
	NodeList<Type> *p = t->next;
	NodeList<Type> *q = NULL;
	t->next = first;
	first->prio = t;
	p->prio = NULL;
	last = t;
	first->data = 1;
	while (p != first)
	{
		head_insert(p->data);
		q = p;
		p = p->next;
		delete q;
	}
}

// 清空
template<class Type>
void List<Type>::clear()
{
	if (first->data == 0)
	{
		return;
	}
	while (first->next != first)
	{
		tail_delete();
	}
}

// 摧毁
template<class Type>
void List<Type>::destroy()
{
	clear();
	delete first;
}

// 退出系统
template<class Type>
void List<Type>::quit_system(Type &x)
{
	x = 0;
}

主函数:

// 用c++实现单链表

#include "DCList.h"

int main()
{
	List<int> mylist;
	int input = 1;
	int insert;
	while (input)
	{
		cout << "*********************************************************************" << endl;
		cout << "*     [1] show_list                       [2] tail_insert           *" << endl;
		cout << "*     [3] head_insert                     [4] sort                  *" << endl;
		cout << "*     [5] head_delete                     [6] tail_delete           *" << endl;
		cout << "*     [7] val_insert           [8] find                  *" << endl;
		cout << "*     [9] val_delete                      [10] length               *" << endl;
		cout << "*     [11] reverse                        [12] clear                *" << endl;
		cout << "*     [13] destroy                        [14] quit_system          *" << endl;
		cout << "*********************************************************************" << endl;
		cout << "please choose:";
		cin >> input;
		switch (input)
		{
		case 1:
			mylist.show_list();
			break;
		case 2:
			cout << "please enter the number want to insert(-1 end):";
			while (cin >> insert, insert != -1)
			{
				mylist.tail_insert(insert);
			}
			break;
		case 3:
			cout << "please enter the number want to insert(-1 end):";
			while (cin >> insert, insert != -1)
			{
				mylist.head_insert(insert);
			}
			break;
		case 4:
			mylist.sort();
			break;
		case 5:
			mylist.head_delete();
			break;
		case 6:
			mylist.tail_delete();
			break;
		case 7:
			cout << "please enter the number want to insert:";
			cin >> insert;
			mylist.val_insert(insert);
			break;
		case 8:
			cout << "please enter the number want to find:";
			cin >> insert;
			if (mylist.find(insert) == NULL)
			{
				cout << "the number is not exist!" << endl;
			}
			else
			{
				cout << "the number at the " << mylist.find(insert) << endl;
			}
			break;
		case 9:
			cout << "please enter the number want to delete:";
			cin >> insert;
			mylist.val_delete(insert);
			break;
		case 10:
			cout << "the length is" << "  " << mylist.length() << endl;
			break;
		case 11:
			mylist.reverse();
			break;
		case 12:
			mylist.clear();
			break;
		case 13:
			mylist.destroy();
			break;
		case 14:
			mylist.quit_system(input);
			break;
		default:
			break;
		}
	}
	return 0;
}

头删:

头插:

反转:

尾删:

尾插:

按值插入:

清空:

排序:

按值删除:

时间: 2024-10-12 17:48:14

【数据结构】双循环链表(c++)的相关文章

C语言数据结构——双循环链表的插入操作顺序

双向链表与单链表的插入操作的区别 双向链表因为存在前驱指针和后继指针所以需要修改的指针多于单链表,但指针改动的顺序同样重要 单链表的插入 eg:在节点p的后面插入指针s s->next=p->next;//首先要使要插入的指针指向p->next p->next=s;//再将p的后继指向插入的s即可 注意! 顺序不能调换,否则在将p->next指向s后,原来由p->next指向的节点将会迷失在内存中,很难找到! 双向循环链表的插入 eg:将新的节点插入p节点的后面 s-&

循环链表之双循环链表

接着上一篇博文http://12172969.blog.51cto.com/12162969/1918256,把循环链表里的双循环链表的基本操纵按照我个人的理解进行总结一下. 依然沿袭过去的风格,进入双循环链表之前,先提另一种结构,双向链表,先有了双向链表再有了双循环链表.这两种结构和单链表一样都有带头结点和不带头结点之分.我们先来看一下这几种结构的结构图: 双链表 双循环链表 既然单向链表有普通的链表也就是不循环的链表.那么双向链表也一样,也有普通的双向链表和双向循环链表:也有带头结点,不带头

双循环链表(包含头指针与尾指针)

双循环链表(包含头指针与尾指针) 以及基本功能的实现 list_ d_link_c.h #ifndef _LIST_D_LINK_C_ #define _LIST_D_LINK_C_ #include<iostream> #include<assert.h> using namespace std; #define ElemType int typedef struct Node { ElemType data; struct Node *prio; struct Node *ne

基本数据结构:链表(list)

copy from:http://www.cppblog.com/cxiaojia/archive/2012/07/31/185760.html 基本数据结构:链表(list) 谈到链表之前,先说一下线性表.线性表是最基本.最简单.也是最常用的一种数据结构.线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的.线性表有两种存储方式,一种是顺序存储结构,另一种是链式存储结构. 顺序存储结构就是两个相邻的元素在内存中也是相邻的.这种存储方式的优点是

编程算法 - 有序双循环链表的插入 代码(C)

有序双循环链表的插入 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 有序双循环链表的插入, 需要找到插入位置, 可以采用, 两个指针, 一个在前, 一个在后. 保证前面的小于等于插入值, 后面的大于等于插入值. 特殊情况, 首尾插入(大于或小于整个链表)或单节点, 判断条件为后指针指向首节点. 则需要直接插入. 插入链表头, 需要调整链表头节点. 代码22行. 代码: /* * main.cpp * * Created on: 2014.9.18

数据结构之链表单向操作总结

链表是数据结构的基础内容之一,下面就链表操作中的创建链表.打印链表.求取链表长度.判断链表是否为空.查找结点.插入结点.删除结点.逆转链表.连接链表.链表结点排序等进行总结. 1.创建表示结点的类,因为链表操作中需要比较结点,因此结点需要实现comparable接口. public class Node implements Comparable<Node> { private Object data; private Node next; //构造函数 public Node() { thi

数据结构-复杂链表的复杂

题目:请实现函数ComplexListNode*  Clone(ComplexListNode* pHead),复杂一个复杂链表.在复杂链表中,每个节点除了有一个Next指针指向下一个节点外,还有一个Sibling指向链表中的任意节点或者NULL. 分析:第一反应是先复制Next,再复制Sibling.但是这种方式需要两次遍历.时间性不是很好.所以利用一个长链表方式解决时间效率. /* 剑指offer面试题26 */ #include <iostream> #include <cstri

AT&amp;T汇编语言与GCC内嵌汇编,Linux内核数据结构之链表

最近在看<Linux内核源代码情景分析>,作者毛德操.书中刚开始介绍了AT&T汇编语言与GCC内嵌汇编,以及Linux内核数据结构之链表.可惜书中介绍的不够全面.因为推荐大家阅读下面两篇文章.很不错. AT&T汇编语言与GCC内嵌汇编:http://grid.hust.edu.cn/zyshao/Teaching_Material/OSEngineering/Chapter2.pdf. Linux内核数据结构之链表:http://www.cnblogs.com/Anker/p/

数据结构:链表的基本操作(创建,删除,插入,逆序,摧毁)

代码注释比较详细: #include <iostream> #include <cstdlib> using namespace std; struct Node{ int data; Node* next; }; Node* head = NULL; bool create() { head = (Node*)malloc(sizeof(Node)); if(NULL == head) return false; head->data = 0; head->next

数据结构--单向链表

C语言中,我们在使用数组时,会需要对数组进行插入和删除的操作,这时就需要移动大量的数组元素,但在C语言中,数组属于静态内存分配,数组在定义时就必须指定数组的长度或者初始化.这样程序一旦运行,数组的长度就不能再改变,若想改变,就只能修改源代码.实际使用中数组元素的个数也不能超过数组元素的最大长度,否则就会发生下标越界的错误(这是新手在初学C语言时肯定会遇到的问题,相信老师也会反复强调!!!但这种问题肯定会遇到,找半天找不到错误在哪,怪我咯???).另外如果数组元素的使用低于最大长度,又会造成系统资