自己动手实现数据结构模板(1):双向链表


date: 2018-09-27 12:42:30+00:00
原标题: 自己动手实现数据结构模板(1):双向链表
原链接: https://www.dreamoftime0.com/2018/09/27/%e8%87%aa%e5%b7%b1%e5%8a%a8%e6%89%8b%e5%ae%9e%e7%8e%b0%e5%8f%8c%e5%90%91%e9%93%be%e8%a1%a8/

今天忽然心血来潮,自己动手实现了一个简单的双向链表和基本功能,大致实现了如下功能

dtsListNode为结点类,包括值value、前向指针pre和后向指针next。

dtsList为双向链表,能够通过begin和end函数获得首地址指针和指向最后一个元素之后一个的尾指针,使用empty函数判断是否为空,size返回数据结点个数,print和print_rev输出当前所有结点,以及使用add2Head、add2End、deleteFromHead、deleteFromEnd从首尾增加或删除结点,并能够在删除结点或析构时及时释放占用的内存。

以下为源代码:

#ifndef DTS_LIST_HPP
#define DTS_LIST_HPP
#include
using namespace std;

template
class dtsListNode{
public:
	T value;
	dtsListNode* next;
	dtsListNode* pre;
	dtsListNode(T v,dtsListNode* nextPointer=NULL,dtsListNode* prePointer=NULL)
		:value(v),next(nextPointer),pre(prePointer){}
	dtsListNode():next(NULL),pre(NULL){}
};

template
class dtsList{
protected:
	dtsListNode* pHead;//空的头结点
	dtsListNode* pBegin;//链表第一个数据结点
	dtsListNode* pTail;//链表最后一个数据结点
	dtsListNode* pEnd;//空的尾结点
	inline dtsListNode* insertAfter(dtsListNode* first,T val){
		dtsListNode* second = new dtsListNode(val);
		dtsListNode* third = first->next;

		if(first==pHead)
			pBegin=second;
		if(first==pTail)
			pTail=second;

		first->next=second;
		second->pre=first;
		second->next=third;
		third->pre=second;

		return second;
	}
	inline T deleteAfter(dtsListNode* first){
		T ret;
		if(!first || !first->next || !first->next->next)
			return ret;
		dtsListNode* second=first->next;
		dtsListNode* third=second->next;
		ret=second->value;

		if(first==pHead){//删除结点为pBegin时
			pBegin=third;
		}
		if(second==pTail){//删除结点为pTail时
			if(first!=pHead){
			pTail=first;
			}
			else {//删除最后一个结点时
			pBegin=NULL;
			pTail=NULL;
			}
		}


		delete second;
		first->next=third;
		third->pre=first;

		return ret;
	}

public:
	dtsList(){
		pHead = new dtsListNode();
		pEnd = new dtsListNode();
		pBegin = NULL;
		pTail = NULL;

		pHead->next=pEnd;
		pEnd->pre=pHead;
	}
	inline bool empty(){
		return pBegin==NULL;
	}
	int size(){
		if(empty())
			return 0;
		int ret=0;
		for(dtsListNode* it=pBegin;it!=pEnd;it=it->next){
			++ret;
		}
		return ret;
	}
	dtsListNode* begin(){
		return pBegin;
	}
	dtsListNode* end(){
		return pEnd();
	}
	dtsList& add2End(T val){
		if(!pTail || !pBegin){//当前无数据时
			pBegin=insertAfter(pHead,val);
			pTail=pBegin;
			//print();
		} else {//已有至少一个数据结点,将它加在最后
			insertAfter(pTail,val);
			//print();
		}
		//cout<<"node "<<val<<" added"<<endl;
		return *this;
	}
	dtsList& add2Head(T val){
		if(!pBegin || !pTail){//当前无数据时
			pBegin=insertAfter(pHead,val);
			pTail=pBegin;
			//print();
		} else {//已有至少一个数据结点,将它加在最前面
			insertAfter(pHead,val);//新的第一个数据结点
			//print();
		}
		//cout<<"node "<<val<<" added"<<endl; return *this; } T deleteFromEnd(){ if(pTail){ return deleteAfter(pTail->pre);
		}
		T ret;
		return ret;
	}
	T deleteFromHead(){
		return deleteAfter(pHead);
	}
	void print(const char* separator="->",const char* null_str="空链表"){
		if(pHead->next==pEnd){
			cout<<null_str<<endl;
			return;
		}
		for( dtsListNode* it=pBegin;it!=pEnd;it=it->next ){
				cout<value;
				if(it!=pEnd->pre)
					cout<<separator;

		}
		cout<<endl;
	}
	void print_rev(const char* separator="<-",const char* null_str="空链表"){ if(pHead->next==pEnd){
			cout<<null_str<<endl;
			return;
		}
		for( dtsListNode* it=pTail;it!=pHead;it=it->pre ){
				cout<value;
				if(it!=pHead->next)
					cout<<separator;
		}
		cout<<endl;
	}
	virtual ~dtsList(){
		dtsListNode* node2Delete=pHead;
		dtsListNode* nextNode2Delete;
		while(node2Delete){
			nextNode2Delete=node2Delete->next;
			//cout<<"node "<value<<" deleted."<<endl;
			delete node2Delete;

			node2Delete=nextNode2Delete;
		}
		//cout<<"list freed"<<endl;
	}
};


#endif // !DTS_LIST_HPP

以下为测试主函数

#include<iostream>
#include<string>
#include"dtsList.hpp"
using namespace std;

int main(){
    dtsList<string> l;
    l.add2Head("one");
    l.add2End("two");
    l.add2End("three");
    l.add2Head("zero");

    l.print("->");
    l.print_rev();
    cout<<"size:"<<l.size()<<endl;

    cout<<l.deleteFromEnd()<<" 被删除"<<endl;
    l.print("->");
    cout<<"size:"<<l.size()<<endl;

    cout<<l.deleteFromHead()<<" 被删除"<<endl;
    l.print("->");
    cout<<"size:"<<l.size()<<endl;

    cout<<l.deleteFromHead()<<" 被删除"<<endl;
    l.print("->");
    cout<<"size:"<<l.size()<<endl;

    cout<<l.deleteFromHead()<<" 被删除"<<endl;
    l.print("->");
    cout<<"size:"<<l.size()<<endl;
}

输出:

zero->one->two->three
three<-two<-one<-zero 
size:4 
three 被删除 zero->one->two
size:3
zero 被删除
one->two
size:2
one 被删除
two
size:1
two 被删除
空链表
size:0

按任意键继续
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值