C++双向链表

C++双向链表

双向链表顾名思义就是每个结点具有两个指针,一个指向前一个结点,一个指向后一个结点,我们不必拘束与单链表的创建遍历操作等,这样大大减少了使用中存在的效率问题。

在单链表中,我们有一个数据域还有一个指针域,数据域用来存储相关数据,而指针域负责链表之间的“联系”,双向链表具有两个指针域一个负责向后连接,一个负责向前连接

//单链表结构
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;  
}  

双向链表的遍历来说我只给出了前序遍历的代码,没有写后序遍历的代码,这其实是差不多的,但是因为双向链表可以进行两个方向的遍历,这给我们带来了很大的方便。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值