经典数据结构--双向链表

双向链表是数据存储的一种表达方式。相比单链表本身,双向链表有一个很重要的优势就是,可以回头,然而也因此需要付出多个指针的存储空间代价。代码如下所示:

#ifndef DOUBLELIST_HHH
#define DOUBLELIST_HHH

#include <stdio.h>

template<typename T>
class CDoubleList;

template<typename T>
struct SDNode{
private:
    T m_nData;
	SDNode* m_pLeft;
	SDNode* m_pRight;
public:
	// constructors;
	friend CDoubleList<T>;
	SDNode();
	SDNode(const T& data);
	~SDNode();
};


template<typename T>
class CDoubleList{
public:
	// constructors;
	CDoubleList();
	~CDoubleList();
	// methods;
	// Length;
    int mLength() const;
	// Find;
	bool mFind(const T& data) const;
	// Delete;
	CDoubleList<T>& mDelete(int k, const T& data);
	// Insert;
	CDoubleList<T>& mInsert(int k, const T& data);
private:
	SDNode<T>* m_pHead;
	SDNode<T>* m_pLast;
};


template<typename T>
SDNode<T>::SDNode():
	m_pLeft(NULL), m_pRight(NULL) {}


template<typename T>
SDNode<T>::SDNode(const T& data):
	m_pLeft(NULL), m_pRight(NULL) {
    m_nData = data;
}

template<typename T>
SDNode<T>::~SDNode(){}

template<typename T>
CDoubleList<T>::CDoubleList(){
	m_pHead = new SDNode<T>;
	m_pLast = new SDNode<T>;
	m_pHead -> m_pLeft = NULL;
	m_pHead -> m_pRight = m_pLast;
	m_pLast -> m_pLeft = m_pHead;
	m_pLast -> m_pRight = NULL;
}

template<typename T>
CDoubleList<T>::~CDoubleList(){
	SDNode<T>* pTmp;
	while(m_pHead != m_pLast){
         pTmp = m_pHead -> m_pRight;
		 delete m_pHead;
		 m_pHead = pTmp;
	}
	if(m_pLast != NULL)
		delete m_pLast;
}

template<typename T>
CDoubleList<T>& CDoubleList<T>::mInsert(int k, const T& data){
	SDNode<T>* pTmp = m_pHead;
	if(k < 0)
		printf("Wrong input of Insert\n");
	else{
	        while(k > 0){
			    pTmp = pTmp -> m_pRight;	
                k --;
				if(pTmp == m_pLast)
                    break;
			}
			if(k != 0)
				printf("k is too large to insert\n");
			if(k == 0){
                SDNode<T>* pInsert = new SDNode<T>(data);
                SDNode<T>* pPar = pTmp->m_pLeft; 

                pPar -> m_pRight = pInsert;
				pInsert -> m_pLeft = pPar;

				pTmp -> m_pLeft = pInsert;
				pInsert -> m_pRight = pTmp;
			}
	}
	return *this;
}

template<typename T>
CDoubleList<T>& CDoubleList<T>::mDelete(int k, const T& data){
    SDNode<T>* pTmp = m_pHead;
	while(k > 0){
		pTmp = pTmp -> m_pRight;
		k --;
		if(pTmp == m_pLast)
			break;
	}
    
	if(k > 0)    // pTmp == m_pLast;
		printf("No data can find to delete\n");
	else{
		if(pTmp == m_pLast)
			printf("No data can find to delete\n");
        if(data == pTmp -> m_nData){
			printf("delete data find\n");
			SDNode<T>* pPar = pTmp -> m_pLeft;
			SDNode<T>* pNext = pTmp -> m_pRight;
            
			delete pTmp;

			pPar -> m_pRight = pNext;
			pNext -> m_pLeft = pPar;
		}

	}
	return *this;
}


template<typename T>
int CDoubleList<T>::mLength() const{
	SDNode<T>* pTmp = m_pHead -> m_pRight;
	int i = 0;
	while(pTmp != m_pLast){
		pTmp = pTmp -> m_pRight;
		i ++;
	}
    return i;
}

template<typename T>
bool CDoubleList<T>::mFind(const T& data) const{
	SDNode<T>* pTmp = m_pHead;
	while(pTmp != m_pLast){
		pTmp = pTmp -> m_pRight;
		if(data == pTmp -> m_nData)
			return true;
	}
	return false;
}
#endif

测试代码:

#include <iostream>
#include <stdlib.h>
#include "CircularLink.h"
#include "DoubleList.h"
using namespace std;

int main(){
    /*CCircularLink<int> link;
	link.mInsert(1);
	cout << link.mFind(1) << endl;
	link.mInsert(2);
	link.mInsert(3);
	cout << link.mFind(2) << endl;
	cout << link.mFind(3) << endl;
	cout << link.mFind(4) << endl;
	link.mDelete();
	link.mDelete();
	link.mDelete();*/
    
	CDoubleList<int> list;
	list.mInsert(1,1);
	list.mInsert(2,2);
	cout << list.mFind(1) << endl;;
	cout << list.mFind(2) << endl;
	cout << list.mLength() << endl;
	list.mDelete(1,1);
	list.mDelete(2,2);
	list.mDelete(1,2);
	cout << list.mLength() << endl;
	system("pause");
	return 0;
}

测试结果:

1
1
2
delete data find
No data can find to delete
delete data find
0
请按任意键继续. . .


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值