`
宫庆义
  • 浏览: 17304 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

数据结构学习----双向循环链表

阅读更多
图1 双向循环链表






#include <stdio.h>      
#include <stdlib.h>      
#include <iostream>      
using namespace std;      
     
#pragma once      
void Error(string error)      
{      
    cout<<error<<endl;      
    system("pause");      
    exit(1);      
}      
    
#pragma once
#pragma region
//双向循环链表类
//测试日期 2010-3-4
#ifndef DCirNode_H
#define DCirNode_H
template<class T>
class DCirNode
{
public:
	DCirNode<T> *next;
	DCirNode<T> *prior;
	T data;

	DCirNode<T>(DCirNode<T> *_next=NULL,DCirNode<T> *_prior=NULL)          
	{next=_next; prior=_prior;}
	DCirNode<T>(T item,DCirNode<T> *_next=NULL,DCirNode<T> *_prior=NULL)     
	{data=item;next=_next; prior=_prior;}  
};
#endif

#ifndef DCIRLIST_H
#define DCIRLIST_H
template<class T>
class DCirList 
{
private:
	DCirNode<T> *head;                            //链表的头指针
	DCirNode<T> *current;                         //当前结点指针
	int size;                                     //链表长度
public:
	DCirList();                                   //构造函数
	~DCirList(){ClearList();}                     //析构函数
	void ClearList();                             //将链表置为空表 
	int Size()const{return size;}                 //返回链表的长度 

	DCirNode<T>* GetItem(int pos);                //取得第pos个元素的地址

	void PushFront(T data);                       //在链表首部添加元素
	void PushBack(T data);                        //在链表尾部添加元素
	T PopFront();                                 //删除头节点 
	T PopBack();                                  //删除尾节点 
	T GetFront();                                 //取得头部元素
	T GetBack();                                  //取得尾部元素

	DCirNode<T>* GetCurrent();                    //返回当前结点指针
	DCirNode<T>* SetCurrent(int pos);             //令current指向第i个结点


	DCirNode<T>* Next();                          //令current指向后一个结点
	DCirNode<T>* Previous();                      //令current指向前一个结点

	T GetData(int pos);                           //取得第pos个表项的值
	void SetData(int pos,T data);                 //修改第pos个表项的值为x
	void Insert(int pos,T data);                  //在位置pos处插入x
	T Delete(int pos);                            //删除第pos个表项 

	bool IsEmpty()const;                          //判断表是否为空

	DCirList<T>& operator=(DCirList<T>& list);    //运算符重载 
};
#endif
#pragma endregion



#pragma region
template<class T>
DCirList<T>::DCirList()
{ 
	current=head=new DCirNode<T>();
	head->next=head;
	head->prior=head;
	size=0; 
}
template<class T>
void DCirList<T>::ClearList()
{
	DCirNode<T>* node;
	while(head->next!=head)
	{
		node=head->next;
		head->next=node->next;
		delete node;
	}
	node=NULL;
	size=0;
}

template<class T>
DCirNode<T>* DCirList<T>::GetItem(int pos)
{
	if(pos<-1||pos>=size)
		return NULL;
	DCirNode<T>* node=head;
	int k=0;
	if(pos<=(size-1)/2)
	{
		while(k<=pos)
		{node=node->next;k++;}
	}
	else
	{
		while(k<size-pos)
		{node=node->prior;k++;}
	}
	return node;
}

template<class T>
void DCirList<T>::PushFront(T data)
{
	DCirNode<T> *node=new DCirNode<T>(data);

	head->next->prior=node;
	node->next=head->next;
	node->prior=head;
	head->next=node;
	size++;
}

template<class T>
void DCirList<T>::PushBack(T data)
{
	DCirNode<T> *node=new DCirNode<T>(data);

	head->prior->next=node;
	node->prior=head->prior;
	node->next=head;
	head->prior=node;
	size++;
}

template<class T>
T DCirList<T>::PopFront()
{
	DCirNode<T> *node=head->next;
	if(node!=head)
	{
		T data=node->data;
		head->next=node->next;
		head->next->prior=head;
		size--;
		delete node;
		node=NULL;
		return data;
	}
	else
		Error("弹出数据出错!");
}

template<class T>
T DCirList<T>::PopBack()
{
	DCirNode<T> *node=head->prior;
	if(node!=head)
	{
		T data=node->data;
		head->prior=node->prior;
		head->prior->next=head;
		size--;
		delete node;
		node=NULL;
		return data;
	}
	else
		Error("弹出数据出错!");
}
template<class T>
T DCirList<T>::GetFront()
{
	if(head->next!=head) 
		return head->next->data;
	else
		Error("读取数据出错!");
}
template<class T>
T DCirList<T>::GetBack()
{
	if(head->prior!=head)
		return head->prior->data;
	else
		Error("读取数据出错!");
}
template<class T>
DCirNode<T>* DCirList<T>::GetCurrent()
{ return current;}
template<class T>
DCirNode<T>* DCirList<T>::SetCurrent(int pos)
{
	DCirNode<T>* node=GetItem(pos);
	if(node!=NULL)
	{
		current=node; 
		return current;
	}
	else
		Error("当前指针不能为空!");
}
template<class T>
DCirNode<T>* DCirList<T>::Next()
{
	current=current->next;
	return current;
}
template<class T>
DCirNode<T>* DCirList<T>::Previous()
{
	current=current->prior;
	return current;
}

template<class T>
T DCirList<T>::GetData(int pos)
{
	if(pos<0||pos>=size) 
		Error("索引越界!"); 
	DCirNode<T>* node=GetItem(pos);
	if(node==NULL) 
		Error("取值出错!"); 
	else
		return node->data;
}
template<class T>
void DCirList<T>::SetData(int pos,T data)
{
	if(pos<0||pos>=size)
		Error("索引越界!");
	DCirNode<T>* node=GetItem(pos);
	if(node==NULL) 
		Error("赋值出错!"); 
	else
		node->data=data;
}

template<class T>
void DCirList<T>::Insert(int pos, T data)
{
	if(pos<0||pos>size)
		Error("索引越界!");
	DCirNode<T>* node=GetItem(pos-1);
	if(node==NULL)
		Error("添加数据出错!");
	DCirNode<T>* newNode=new DCirNode<T>(data);
	if(newNode==NULL) 
		Error("内存分配错误!"); 
	newNode->next=node->next;
	newNode->prior=node;
	newNode->next->prior=newNode;
	node->next=newNode;
	size++;
}

template<class T>
T DCirList<T>::Delete(int pos)
{
	if(pos<0||pos>=size)
		Error("索引越界");
	DCirNode<T> *node1,*node2;
	node1=GetItem(pos-1);
	node2=node1->next;
	node1->next=node2->next;
	node1->next->prior=node1;
	T data=node2->data;
	delete node2;
	node2=NULL;
	size--;
	return data; 
}
template<class T>
bool DCirList<T>::IsEmpty() const
{
	return (size==0)?true:false;
}
template<class T>
DCirList<T>& DCirList<T>::operator =(DCirList<T> &list)
{
	T data;  
	DCirNode<T> *p=list.GetItem(-1);
	DCirNode<T> *src=p; 
	DCirNode<T> *des=head;
	while(src->next!=p)
	{
		data=src->next->data;
		des->next=new DCirNode<T>(data);
		des->next->prior=des;

		des=des->next;
		src=src->next;
		size++;
	}
	des->next=head;
	head->prior=des;
	current=head;
	return *this; 
}
#pragma endregion
  • 大小: 9.7 KB
0
1
分享到:
评论

相关推荐

    数据结构--双向循环链表实践

    c语言实现:利用双向循环链表,用户输入一个数使得26个字母的排列发生变化,例如用户输入3,输出结果:DEFGHIJKLMNOPQRSTUVWXYZABC

    严蔚敏-数据结构--链表实现c++实现

    3. **循环链表**:最后一个节点的指针不是NULL,而是指向链表的第一个节点,形成一个环。这在某些算法中很有用,如Floyd判断环算法。 4. **链表的操作**:包括初始化(创建空链表)、插入(在头部、尾部或特定位置...

    算法大全-面试题-链表-栈-二叉树-数据结构

    "算法大全-面试题-链表-栈-二叉树-数据结构"这个压缩包文件提供了丰富的知识资源,旨在帮助学习者深入理解和应用这些核心概念。 链表是一种线性数据结构,与数组不同,它的元素在内存中不是连续存储的。链表由一...

    内核数据结构之双向循环链表

    双向循环链表是一种重要的数据结构,广泛用于实现各种内核级别的数据组织,如内存管理、进程控制块等。本篇文章将深入探讨这种数据结构,包括`list_head`、`list_entry`以及相关的遍历宏`list_for_each`。 首先,...

    算法-数据结构和算法-8-双向链表.rar

    - 双向循环链表:在双向链表的基础上,首尾节点形成环状,常用于实现循环队列和某些特定的搜索算法。 - 双向链表和栈的结合:在实现某些算法,如LRU缓存淘汰策略时,会用到栈和双向链表的组合。 6. **数据结构的...

    数据结构课程设计报告基于双向循环链表的通讯录设计

    ### 数据结构课程设计报告:基于双向循环链表的通讯录设计 #### 概要设计 在沈阳航空航天大学的计算机学院,计算机科学与技术专业的学生冯读庆在其数据结构课程设计中,选择了一个既具挑战性又实用的项目——基于...

    链存储结构-双向链表

    而"循环链表"是单链表的一种变体,它的最后一个节点的指针不再为null,而是指向链表的第一个节点,形成一个环状结构,使得遍历可以无限循环。 双向链表的基本操作包括创建、插入、删除、查找和遍历。创建一个双向...

    数据结构--数组、单链表和双链表介绍以及双向链表 数组和链表.pdf

    数据结构--数组、单链表和双链表介绍以及双向链表 数据结构是计算机科学中的一种基本概念,指的是数据的组织和存储方式。数组、链表是两种常见的数据结构,下面将对它们进行介绍。 一、数组 数组是数据结构中的一...

    带头结点的双向循环链表数据结构

    【带头结点的双向循环链表数据结构】 在数据结构中,双向循环链表是一种特殊类型的数据结构,它允许从两个方向遍历链表。在本案例中,我们需要使用C++和Java分别实现这种数据结构,并确保它们符合指定的要求。 在...

    双链表-循环链表-静态链表.pdf

    循环链表则因其实现上的简洁和遍历上的便利,常用于设计实现一些特殊的数据结构如循环队列、循环链表中的哈希表等。静态链表因其实现简单,空间固定,适用于那些数据量变化不大,且可以事先预知节点数量上限的场景。...

    数据结构-链表.pdf

    数据结构-链表 数据结构是计算机科学和信息技术领域中的一个基础概念,指的是...链表是一种非常重要的数据结构,它可以分为单向链表、循环链表和双向循环链表等。链表的优点是插入和删除操作方便,缺点是存取速度慢。

    漫话数据结构-双向链表及基本操作.pptx

    "漫话数据结构-双向链表及基本操作"的讲座涵盖了双向链表的概念、构建、插入和删除操作,以及双向循环链表的特性。这些知识对于理解和掌握数据结构的基础至关重要,同时也是提升编程技能和解决实际问题能力的重要...

    华科计算机学院数据结构实验报告 双向循环链表

    【双向循环链表】是一种特殊的数据结构,它允许节点在链表中前后两个方向移动。在华科计算机学院的数据结构实验中,学生们被要求实现一个使用C++编程的双向循环链表,包括一系列操作,如创建、销毁、置空、求长度、...

    航班订票系统(单向,双向循环链表)

    总结,这个航班订票系统利用了数据结构的优势,以单向链表管理航班,以双向循环链表管理乘客,实现了高效的数据存储和操作。通过合理的设计和实现,该系统能够满足用户的基本需求,为实际的航班预订提供便利。

    数据结构-链表的实现代码(C语言版).rar

    数据结构 -- C语言版 -- 链表的部分实现代码(单向链表、双向链表、循环链表、约瑟夫环等),详细介绍参考数据结构--链表的系列博文。链接为:https://blog.csdn.net/songshuai0223/category_9742561.html。

    数据结构 -- 链表的基本操作

    链表的类型主要有单向链表、双向链表和循环链表。 1. 插入操作: - 在链表头部插入:这是最快的方式,因为只需更新头节点即可。创建新节点,将新节点的数据域设置为要插入的元素,指针域指向原头节点,然后将头...

    双向循环链表源码

    本文将深入探讨双向循环链表的原理、实现方式以及其在实际应用中的价值。 双向循环链表是一种特殊的链表类型,与普通的单向链表不同,它具有两个指针,一个指向前一个节点,另一个指向后一个节点。这种设计使得在...

    c语言 链表 双向链表 双向循环链表

    本文将深入探讨C语言实现的双向链表和双向循环链表,以及如何将这些概念应用于Linux内核。双向链表与单向链表相比,具有更灵活的操作特性,而双向循环链表则在此基础上增加了循环的特性,使得遍历和操作更加方便。 ...

    Linux操作系统中通用双向循环链表的实现分析.pdf

    在Linux内核源代码中,双向循环链表是一种常用的数据结构,它广泛应用于各种场景,如进程就绪队列、专用内存缓冲管理队列、物理内存页面管理队列和定时器队列等等。这些队列中的元素尽管结点类型各异,但都可以看作...

Global site tag (gtag.js) - Google Analytics