Circular Doubly Linked List 双向循环链表 C++ 例子
来源:互联网 发布:手机淘宝如何买东西 编辑:程序博客网 时间:2024/06/05 06:58
What a circular doubly linked list looks like?
Look at Figure1, It is a circular doubly linked list have 8 nodes. If you compare it and the array in Figure2, you will find that each node in doubly linked list points to the next node and pre node in the list. Because of the way that linked lists are structured, you can easily add or remove nodes at the beginning or the end of a list, or even in the middle of the list. Below is a list class with simple property. We will add "Insert", "Delete" and other function later.
template <class T> class List;template <class T>class Node{friend List<T>;private:T data;Node<T>* pre,* next;};template <class T>class List{private:Node<T>* first;}
How to insert a node
There are four cases when you insert a node into the linked list. (1) insert the node at the beginning of the list, (2) insert the node at the middle of the list, (3) insert the node at the end of the list, (4) out of range
(1). The new node will become the new first node in the list.
(3). The new node will become the new tail node in the list.
(4). Throw a exception
We will talk detail about the second case using three figures below.
template<class T>void List<T>::Insert(const int& position, const T& v){if(position < 0 || position > Size()){throw OutOfBounds();}Node<T>* newNode = new Node<T>;newNode->data = v;if(position == 0){// at the beginning of the listif(!first){ //the list is emptyfirst = newNode;first->next = first->pre = first;}else{ //the new node became the first nodenewNode->next = first;first->pre = newNode;newNode->pre = first->pre;first->pre->pre->next = newNode;first = newNode;}}else{ //at the middle or end of the listNode<T>* nodeBeforePostion = first;//find the node before insert positionfor(int i = 1; i < position && nodeBeforePostion; ++i){nodeBeforePostion = nodeBeforePostion->next;}newNode->next = nodeBeforePostion->next;newNode->next->pre = newNode;newNode->pre = nodeBeforePostion;nodeBeforePostion->next = newNode;}++size;}
How to delete a node
There three cases when you delete a node in the list. (1) Delete the first node, (2) Delete a node at the middle position of the list, (3) out of range
(1). The first node's next node become the new first node.
(3). Throw a exception.
Figure 6,7 and 8 show a graphical representation of how the case 2 acts.
template<class T>void List<T>::Delete(const int& position, T& out){if(position < 0 || position > Size() || !first){throw OutOfBounds();}if(position == 0){// at the beginning of the listout = first->data;Node<int>* tmp = first->next;if(tmp == first){ //only one node,just delete itdelete first;first = 0;}else{ // set first node's next node to be the new first node,delete the old first nodefirst->pre->next = first->next;first->next->pre = first->pre;delete first;first = tmp;}}else{//at the middle or end of the listNode<T>* nodeDelete = first;//find the node which need to deletefor(int i = 0; i< position && nodeDelete->next != first; ++i){nodeDelete = nodeDelete->next;}nodeDelete->pre->next = nodeDelete->next;nodeDelete->next->pre = nodeDelete->pre;out = nodeDelete->data;delete nodeDelete;}--size;}
Circular Double Linked List Customized Class
#ifndef _List_#define _List_#include <iostream>using namespace std;//exceptionclass OutOfBounds{public:OutOfBounds(){}};template <class T> class List;template <class T>class Node{friend List<T>;private:T data;Node<T>* pre,* next;};template <class T>class List{//overwrite operator <<template<class T> friend ostream& operator<<(ostream& ,List<T>&);private:Node<T>* first; int size;bool firstTime;//used for print list element.Node<T>* current;public:List(){first = 0; size = 0;}~List();void Delete(const int& position, T& out);void Delete(const int& position);void Insert(const int& position, const T& x);void Push_Back(const T& v);int Size()const;T Front()const;T Back()const;void Begin();void MoveNext();bool Valid();T GetItemData() const;void Clear();};template<class T>ostream& operator<< (ostream& out,List<T>& list){out << "The list's size: " << list.Size() << endl;out << "The list's front: ";try{out << list.Front() << endl;}catch(OutOfBounds ){out << "No element in the list" << endl;}out << "The list's back: ";try{out << list.Back() << endl;}catch(OutOfBounds ){out << "No element in the list" << endl;}out << "Elements in the list:" << endl;for(list.Begin(); list.Valid(); list.MoveNext()){out << list.GetItemData() << ' ';}out << endl;return out;}template<class T>List<T>::~List(){Clear();}template<class T>void List<T>::Delete(const int& position){T value;Delete(position, value);}template<class T>void List<T>::Delete(const int& position, T& out){if(position < 0 || position > Size() || !first){throw OutOfBounds();}if(position == 0){// at the beginning of the listout = first->data;Node<int>* tmp = first->next;if(tmp == first){ //only one node,just delete itdelete first;first = 0;}else{ // set first node's next node to be the new first node,delete the old first nodefirst->pre->next = first->next;first->next->pre = first->pre;delete first;first = tmp;}}else{//at the middle or end of the listNode<T>* nodeDelete = first;//find the node which need to deletefor(int i = 0; i< position && nodeDelete->next != first; ++i){nodeDelete = nodeDelete->next;}nodeDelete->pre->next = nodeDelete->next;nodeDelete->next->pre = nodeDelete->pre;out = nodeDelete->data;delete nodeDelete;}--size;}template<class T>void List<T>::Insert(const int& position, const T& v){if(position < 0 || position > Size()){throw OutOfBounds();}Node<T>* newNode = new Node<T>;newNode->data = v;if(position == 0){// at the beginning of the listif(!first){ //the list is emptyfirst = newNode;first->next = first->pre = first;}else{ //the new node became the first nodenewNode->next = first;first->pre = newNode;newNode->pre = first->pre;first->pre->pre->next = newNode;first = newNode;}}else{ //at the middle or end of the listNode<T>* nodeBeforePostion = first;//find the node before insert positionfor(int i = 1; i < position && nodeBeforePostion; ++i){nodeBeforePostion = nodeBeforePostion->next;}newNode->next = nodeBeforePostion->next;newNode->next->pre = newNode;newNode->pre = nodeBeforePostion;nodeBeforePostion->next = newNode;}++size;}template<class T>void List<T>::Push_Back(const T& v){Node<T>* newNode = new Node<T>;newNode->data = v;if(!first){ // the list is emptyfirst = newNode;first->next = first->pre = first;}else{Node<T>* lastNode = first->pre;first->pre = newNode;newNode->next = first;lastNode->next = newNode;newNode->pre = lastNode;}++size;}template<class T>int List<T>::Size() const{return size;}template<class T>T List<T>::Front() const{if(!first){throw OutOfBounds();}else{return first->data;}}template<class T>T List<T>::Back() const{if(!first){throw OutOfBounds();}else{return first->pre->data;}}template<class T>void List<T>::Begin(){current = first;firstTime = true;}template<class T>void List<T>::MoveNext(){current = current->next;}template<class T>bool List<T>::Valid(){if(!first || (current == first && !firstTime)){return false;}else{firstTime = false;return true;}} template<class T>T List<T>::GetItemData()const{return current->data;}template<class T>void List<T>::Clear(){while(Size() != 0){Delete(0);}size = 0;}#endif
Test the class
// CustomizedList.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include "List.h"#include <iostream>using namespace std;int _tmain(int argc, _TCHAR* argv[]){List<int> list;int deleteValue;cout << "after initialize list" << endl;cout << list;cout << "try to delete with no element" << endl;try{list.Delete(0);}catch(OutOfBounds){cout << "delete error" << endl;}cout << "after call list.Insert(1,1)" << endl;try{list.Insert(1,1);}catch(OutOfBounds){cout << "insert error" << endl;}cout << list;cout << "after call list.Insert(0,1)" << endl;try{list.Insert(0,1);}catch(OutOfBounds){cout << "insert error" << endl;}cout << list;cout << "try to delete out range" << endl;try{list.Delete(2);}catch(OutOfBounds){cout << "delete error" << endl;}cout << list;cout << "after call list.Push_Back(2) " << endl;list.Push_Back(2);cout << list;cout << "delete position 0" << endl;try{list.Delete(0, deleteValue);}catch(OutOfBounds){cout << "delete error" << endl;}cout << "delete value:" << deleteValue << endl;cout << list;for(int i =0;i< 10; ++i){list.Push_Back(i);}cout << list;cout << "after call list.Clear()" << endl;list.Clear();cout << list;int i;cin >> i;return 0;}
http://www.waitingfy.com/?p=487
- Circular Doubly Linked List 双向循环链表 C++ 例子
- 双向链表(Doubly Linked List)
- Generic double circular linked list - 通用双向循环链表C语言实现
- 逆置双向链表 Reverse a doubly linked list
- 循环链表(Circular Linked List)
- Lead the bidirectional circular linked list——双向循环链表
- 双向链表的C++实现 Implement of Doubly Linked List
- 【数据结构】Doubly-Linked List双向链表(更新时间:2016-04-13)
- Linked List {singly linked list -> doubly linked list -> circular linked list}
- Glib学习(2) 双向链表 Doubly-Linked Lists
- 用数组实现栈(Stacks)、队列(Queue)和双向链表(Doubly Linked List)的伪代码
- 链表ALDS1-3-C:Doubly Linked List
- Doubly linked list
- Doubly Linked List
- 双向循环链表list(C++)
- Double Circular Linked List
- Linked List/Singly-Linked List/Doubly-Linked List
- 双向循环链表list
- c# 程序只能运行一次(多次运行只能打开同一个程序) 并激活第一个实例,使其获得焦点,并在最前端显示.
- 为RichTextBox添加快捷功能菜单(复制, 剪切,粘贴,全选)
- Android如何防止apk程序被反编译
- Oracle SQL Trace 和 10046 事件
- iPhone 开发过程中的一些小技术的总结
- Circular Doubly Linked List 双向循环链表 C++ 例子
- linux shell 实用编程记录
- ORACLE 视图
- Jsp两种注释方式的比较。
- webView读取数据----乱码解决
- Calendar类使用实例
- 单例模式
- Java陷阱(五)
- iphone push notification 消息推送(转)