赞
踩
双向链表顾名思义就是每个结点具有两个指针,一个指向前一个结点,一个指向后一个结点,我们不必拘束与单链表的创建遍历操作等,这样大大减少了使用中存在的效率问题。
在单链表中,我们有一个数据域还有一个指针域,数据域用来存储相关数据,而指针域负责链表之间的“联系”,双向链表具有两个指针域,一个负责向后连接,一个负责向前连接。
- //单链表结构
- template<class T>
- struct List{
- T data;
- struct List* next;
- };
- //双向链表结构
- template<class T>
- struct DNode{
- public:
- T value;
- DNode *prev;
- DNode *next;
- };
同单链表一样,对双向链表的操作也有创建,插入,遍历,删除,销毁。
双向链表的创建
- struct DNode{
- public:
- T value;
- DNode *prev;
- DNode *next;
- public:
- DNode(){
- }
- DNode(T t,DNode *prev,DNode *next){
- this->value=t;
- this->prev=prev;
- this->next=next;
- }
- };
在创建双向链表的时候,我们需要初始化的有两个指针。同单链表一样,我们需要一个头指针来标志链表的信息。因此我们可以写出该函数的定义:运用构造函数创建双向链表
双向链表具体操作:
- template<class T>
- class DoubleCircleList{
- public:
- DoubleCircleList(); //构造函数 创建链表
- ~DoubleCircleList(); //析构函数 销毁链表
- int size(); //长度
- int is_empty();//判断是否为空
- T get(int index); //返回index值的位置
- T get_first();//返回第一个位置
- T get_last();//返回最后一个位置
- int insert(int index,T t);//在index位置后插入数值
- int insert_first(T t);//在头插入
- int append_last(T t);//在尾插入
- int Delete(int index);//删除index值
- int Delete_first();//删除头结点
- int Delete_last();//删除尾结点
- private:
- int count;
- DNode<T>* phead;
- DNode<T>* get_node(int index);
- };
1.计算链表的长度
- template<class T>
- DoubleCircleList<T>::DoubleCircleList():count(0){
- //创建“表头 ,注意:表头没有存储数据!
- phead=new DNode<T>();
- phead->prev=phead->next=phead;
- //设置链表计数为0
- //cout=0;
- }
2.销毁链表
- //析构函数 销毁链表
- template<class T>
- DoubleCircleList<T>::~DoubleCircleList(){
- DNode<T>* ptmp;
- DNode<T>* pnode=phead->next;
- while(pnode!=phead){ //一直循环往后找
- ptmp=pnode; //
- pnode=pnode->next;
- delete ptmp;
- }
- delete phead;
- phead=NULL;
- }
3.计算结点的数目
- //返回结点数目
- template<class T>
- int DoubleCircleList<T>::size(){
- return count;
- }
4.判断链表是否为空
- template<class T>
- int DoubleCircleList<T>::is_empty(){
- return count==0;
- }
5.寻找结点位置
- template<class T>
- DNode<T>* DoubleCircleList<T>::get_node(int index){
- //判断参数有效性
- if(index<0||index>=count){
- cout<<"get node failed! the index in out of bound!"<<endl;
- return NULL;
- }
- //正向查找
- if(index<=count/2){
- int i=0;
- DNode<T>* pindex=phead->next;
- while(i++<index){
- pindex=pindex->next;
- }
- return pindex;
- }
- //反向查找
- int j=0;
- int rindex=count-index-1;
- DNode<T>* prindex=phead->prev;
- while(j++<rindex){
- prindex=prindex->prev;
- }
- return prindex;
- }
6.返回结点位置的值
- template<class T>
- T DoubleCircleList<T>::get(int index){
- return get_node(index)->value;
- }
7.获取第一个结点的值
- template<class T>
- T DoubleCircleList<T>::get_first(){
- return get_node(0)->value;
- }
8.获取最后一个结点的值
- template<class T>
- T DoubleCircleList<T>::get_last(){
- return get_node(count-1)->value;
- }
9.将结点插入index之后
- template<class T>
- int DoubleCircleList<T>::insert(int index,T t){
- if(index==0)
- return insert_first(t);
- DNode<T>* pindex=get_node(index);
- DNode<T>* pnode=new DNode<T>(t,pindex->prev,pindex);
- pindex->prev->next=pnode;
- pindex->prev=pnode;
- count++;
- return 0;
-
- }
10.结点插入到第一个位置
- //将结点插入到第一个结点处
- template<class T>
- int DoubleCircleList<T>::insert_first(T t){
- DNode<T>* pnode=new DNode<T>(t,phead,phead->next);
- phead->next->prev=pnode;
- phead->next=pnode;
- count++;
- return 0;
- }
11.结点插入到最后一个位置
- template<class T>
- int DoubleCircleList<T>::append_last(T t){
- DNode<T>* pnode=new DNode<T>(t,phead->prev,phead);
- phead->prev->next=pnode;
- phead->prev=pnode;
- count++;
- return 0;
- }
12.删除index结点.
- template<class T>
- int DoubleCircleList<T>::Delete(int index){
- DNode<T>* pindex=get_node(index);
- pindex->next->prev=pindex->prev;
- pindex->prev->next=pindex->next;
- delete pindex;
- count--;
- return 0;
- }
13.删除第一个结点
- template<class T>
- int DoubleCircleList<T>::Delete_first(){
- return Delete(0);
- }
14.删除最后一个结点
- template<class T>
- int DoubleCircleList<T>::Delete_last(){
- return Delete(count-1);
- }
完整代码:
- //DoubleCircleList.h
- #include<iostream>
- using namespace std;
- template<class T>
- struct DNode{
- public:
- T value;
- DNode *prev;
- DNode *next;
- public:
- DNode(){
- }
- DNode(T t,DNode *prev,DNode *next){
- this->value=t;
- this->prev=prev;
- this->next=next;
- }
- };
- template<class T>
- class DoubleCircleList{
- public:
- DoubleCircleList(); //构造函数 创建链表
- ~DoubleCircleList(); //析构函数 销毁链表
- int size(); //长度
- int is_empty();//判断是否为空
- T get(int index); //返回index值的位置
- T get_first();//返回第一个位置
- T get_last();//返回最后一个位置
- int insert(int index,T t);//在index位置后插入数值
- int insert_first(T t);//在头插入
- int append_last(T t);//在尾插入
- int Delete(int index);//删除index值
- int Delete_first();//删除头结点
- int Delete_last();//删除尾结点
- private:
- int count;
- DNode<T>* phead;
- DNode<T>* get_node(int index);
- };
- template<class T>
- DoubleCircleList<T>::DoubleCircleList():count(0){
- //创建“表头 ,注意:表头没有存储数据!
- phead=new DNode<T>();
- phead->prev=phead->next=phead;
- //设置链表计数为0
- //cout=0;
- }
- //析构函数
- template<class T>
- DoubleCircleList<T>::~DoubleCircleList(){
- DNode<T>* ptmp;
- DNode<T>* pnode=phead->next;
- while(pnode!=phead){ //一直循环往后找
- ptmp=pnode; //
- pnode=pnode->next;
- delete ptmp;
- }
- delete phead;
- phead=NULL;
- }
- //返回结点数目
- template<class T>
- int DoubleCircleList<T>::size(){
- return count;
- }
- template<class T>
- int DoubleCircleList<T>::is_empty(){
- return count==0;
- }
- template<class T>
- DNode<T>* DoubleCircleList<T>::get_node(int index){
- //判断参数有效性
- if(index<0||index>=count){
- cout<<"get node failed! the index in out of bound!"<<endl;
- return NULL;
- }
- //正向查找
- if(index<=count/2){
- int i=0;
- DNode<T>* pindex=phead->next;
- while(i++<index){
- pindex=pindex->next;
- }
- return pindex;
- }
- //反向查找
- int j=0;
- int rindex=count-index-1;
- DNode<T>* prindex=phead->prev;
- while(j++<rindex){
- prindex=prindex->prev;
- }
- return prindex;
- }
- template<class T>
- T DoubleCircleList<T>::get(int index){
- return get_node(index)->value;
- }
- //获取第1个结点值
- template<class T>
- T DoubleCircleList<T>::get_first(){
- return get_node(0)->value;
- }
- //获取最后一个结点值
- template<class T>
- T DoubleCircleList<T>::get_last(){
- return get_node(count-1)->value;
- }
- //将结点插入到index位置之前
- template<class T>
- int DoubleCircleList<T>::insert(int index,T t){
- if(index==0)
- return insert_first(t);
- DNode<T>* pindex=get_node(index);
- DNode<T>* pnode=new DNode<T>(t,pindex->prev,pindex);
- pindex->prev->next=pnode;
- pindex->prev=pnode;
- count++;
- return 0;
-
- }
- //将结点插入到第一个结点处
- template<class T>
- int DoubleCircleList<T>::insert_first(T t){
- DNode<T>* pnode=new DNode<T>(t,phead,phead->next);
- phead->next->prev=pnode;
- phead->next=pnode;
- count++;
- return 0;
- }
- //结点追加到链表末尾
- template<class T>
- int DoubleCircleList<T>::append_last(T t){
- DNode<T>* pnode=new DNode<T>(t,phead->prev,phead);
- phead->prev->next=pnode;
- phead->prev=pnode;
- count++;
- return 0;
- }
- //删除index位置结点
- template<class T>
- int DoubleCircleList<T>::Delete(int index){
- DNode<T>* pindex=get_node(index);
- pindex->next->prev=pindex->prev;
- pindex->prev->next=pindex->next;
- delete pindex;
- count--;
- return 0;
- }
- //删除第一个结点
- template<class T>
- int DoubleCircleList<T>::Delete_first(){
- return Delete(0);
- }
- //删除最后一个结点
- template<class T>
- int DoubleCircleList<T>::Delete_last(){
- return Delete(count-1);
- }
-
- //DoubleCircleList.cpp
- #include <iostream>
- #include "DoubleCircleList.h"
- /* run this program using the console pauser or add your own getch, system("pause") or input loop */
- using namespace std;
- void int_test()
- {
- int iarr[4] = {10, 20, 30, 40};//定义一个数组
-
- cout << "\n开始测试 int数据" << endl;
- // 创建双向链表
- DoubleCircleList<int>* pdlink = new DoubleCircleList<int>();
-
- pdlink->insert(0, 20); // 将 20 插入到第一个位置
- pdlink->append_last(10); // 将 10 追加到链表末尾
- pdlink->insert_first(30); // 将 30 插入到第一个位置
-
- // 双向链表是否为空
- cout << "is_empty()=" << pdlink->is_empty() <<endl;
- // 双向链表的大小
- cout << "size()=" << pdlink->size() <<endl;
-
- // 打印双向链表中的全部数据
- int sz = pdlink->size();
- for (int i=0; i<sz; i++)
- cout << "pdlink("<<i<<")=" << pdlink->get(i) <<endl;
- }
-
- int main(int argc, char** argv) {
- int_test();
- return 0;
- }
双向循环链表:
- #include<stdio.h>
- #include<stdlib.h>
- #include<malloc.h>
- typedef struct DOUBLE_LIST
- {
- int data;
- struct DOUBLE_LIST *prev;
- struct DOUBLE_LIST *next;
- }double_list;
- double_list *createlist() //创建有n个元素的双向链表 并输入元素
- {
- double_list *head, *p, *q;
- int n,x;
- head = (double_list *)malloc(sizeof(double_list));
- head->prev = head;
- head->next = head;
- p = head;
- printf("输入要创建双向链表的元素的个数:\n");
- scanf("%d",&n);
- for(int i=0;i<n;i++)
- {
- scanf("%d", &x);
- q = (double_list *)malloc(sizeof(double_list));
- q->data = x;
- p->next = q;
- head->prev = q;
- q->prev = p;
- q->next = head;
- p = q;
- }
- return head;
- }
- //遍历并且输出这些元素
- void printlist(double_list *head)
- {
- double_list *p;
- p = head;
- p = p->next;
- while(p!=head)
- {
- printf("%d ", p->data);
- p = p->next;
- }
- printf("\n");
- }
- //得到现在双向链表中的元素的个数
- int lengthlist(double_list *head)
- {
- double_list *p;
- p = head;
- p = p->next;
- int coun = 0;
- while(p!=head)
- {
- coun++;
- p = p->next;
- }
- return coun;
- }
- //在第i个元素之前插入数据data
- void insertlist_f(double_list *head, int i, int data)
- {
- double_list *p = head, *q;
- p = p->next;
- i--;
- while(i--)
- p = p->next;
- q = (double_list *)malloc(sizeof(double_list));
- q->data = data;
- (p->prev)->next = q;
- q->prev = p->prev;
- q->next = p;
- p->prev = q;
- }
- //删除第i个位置的元素
- void deletelist_i(double_list *head, int i)
- {
- double_list *p = head;
- p = p->next;
- i--;
- while(i--)
- p = p->next;
- (p->prev)->next = p->next;
- (p->next)->prev = p->prev;
- free(p);
- }
- //删除值为x的元素
- void deletelist_x(double_list *head, int x)
- {
- double_list *p = head, *q;
- p = p->next;
- while(p!=head)
- if(p->data == x)
- {
- q = p->next;
- (p->prev)->next = p->next;
- (p->next)->prev = p->prev;
- free(p);
- p = q;
- }
- else
- p = p->next;
- }
- //对双向链表进行排序
- void sortlist(double_list *head) //升序
- {
- double_list *p = head, *q, *t;
- p = p->next;
- for(;p!=head;p=p->next)
- for(t = p->next;t!=head;t=t->next)
- {
- if(p->data > t->data)
- {
- int a = p->data;
- p->data = t->data;
- t->data = a;
- }
- }
- }
- int main()
- {
- double_list *head;
- head = createlist();
- deletelist_x(head, 2);
- //sortlist(head);
- printlist(head);
- insertlist_f(head, 2, 2);
- printlist(head);
-
- return 0;
- }
双向链表的遍历来说我只给出了前序遍历的代码,没有写后序遍历的代码,这其实是差不多的,但是因为双向链表可以进行两个方向的遍历,这给我们带来了很大的方便。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。