基于c++11编写的双向链表(实现了构造函数、添加、查找、交换、删除、清空、排序等功能)

基于c++11编写的双向链表

实现:dlist.h

#ifndef DLIST_H
#define DLIST_H
#include <iostream>
#include <string>
#include <stdexcept>

using namespace std;
typedef int ElemData;

struct node{
    ElemData data;
    node* next;
    node* prev;
};

class DList
{
    node *head = NULL;
    node *tail = NULL;
    int len;
public:
	
	//缺省构造函数 
    DList(){
    	len = 0;
    }
    
    //拷贝构造函数 
    DList(const DList &l){  
	    len = 0; 	
        if(l.head!=NULL){        	
            node *pHc = l.head;      //链表l节点指针 
            head = new node();       //为新链表头节点申请空间
            head->data = pHc->data;  //新链表头结点赋值 
            node *pH = head;         //新链表节点指针 
            len++;
            while(pHc!=l.tail){
            	pHc = pHc->next;
                pH->next = new node(); //为新节点分配内存,当前节点的next指针指向新节点
                pH->next->prev = pH; //新节点的prev指针指向当前节点 
                pH = pH->next;                
				pH->data = pHc->data;  
				len++;              
            }            
        }
        else{
            head=tail=NULL;
        }
    }
    
    //赋值运算符重载函数 
    DList& operator = (const DList &l){
    	len = 0;
        if (this == &l){
            return *this;
        }
        len = 0; 	
        if(l.head!=NULL){        	
            node *pHc = l.head;      //链表l节点指针 
            head = new node();       //为新链表头节点申请空间
            head->data = pHc->data;  //新链表头结点赋值 
            node *pH = head;         //新链表节点指针 
            len++;
            while(pHc!=l.tail){
            	pHc = pHc->next;
                pH->next = new node(); //为新节点分配内存,当前节点的next指针指向新节点
                pH->next->prev = pH; //新节点的prev指针指向当前节点 
                pH = pH->next;                
				pH->data = pHc->data;  
				len++;              
            }            
        }
        else{
            head=tail=NULL;
        }
        return *this;
    }
    
    //析构函数 
    ~DList(){
        node *bgn = head;
        while(head!=tail)
        {
            head = head->next;
            delete bgn;//释放内存
            bgn = head;
        }
        len = 0;
    }
    
    int size(){
    	return len;
	}
	void print(){
		for(int i=0;i<len;i++){
	        cout<<at(i)<<" ";  	
		} 
		cout<<endl;
	}
    
    //在尾部添加节点 
    void push_back(ElemData data){
        if(head==NULL){
                head = new node();
                head->data = data;
                len++;
                tail = head;
        }
        else{
            tail->next = new node();
            tail->next->data = data;
            len++;
            tail->next->prev = tail;
            tail = tail -> next;
        }
        return;
    }
    
    //取出节点(按下标) 
    ElemData at(int index){
        node *p;
        p = head;
        if(index>=len)
            throw out_of_range("in at(int index) index out of range");
        else{
            for(int i=0;i<index;i++)
                p = p->next;
        }
        return p->data;
    }
    
    //查找节点 
    int indexOf(ElemData _data){
    	int index = 0;
	    node *p = head;
		while(p->data != _data){ 
			p = p->next;
			index++;
		} 
		if(index >= len) 
		    return -1;
		else
		    return index;
	} 
	//删除节点 
    void removeAt(int index){
    	node *p;
        p = head;
        if(index >= len)
            throw out_of_range("in removeAt(int index) index out of range");             
        else{
        	//移动到要删除的节点处 
            for(int i=0;i<index;i++){
            	p = p->next;
			}               
            p->prev->next = p->next;
            p->next->prev = p->prev;
            delete p;
            p = NULL;
            len--; 
        }  
		return;     
	}
    void clear(){
    	node *bgn = head;
        while(head!=tail)
        {
            head = head->next;
            delete bgn;//释放内存
            bgn = head;
        }
        len = 0;
	}
	
	//交换两节点(交换值) 
	void swap(int i, int j){
		int vi = at(i);
		int vj = at(j);		
		node *p;
        p = head;
		for(int k=0;k<i;k++)
            p = p->next;
        p->data = vj;
        p = head;
		for(int k=0;k<j;k++)
            p = p->next;
        p->data = vi;
	} 
	
	//子表划分函数,返回枢轴值 
	int Partition(DList *l,int low, int high){
		int pivotkey;
		pivotkey = l->at(low); //用子表的第一个记录作为枢轴记录 
		while(low < high){
			while(low < high && l->at(high) >= pivotkey)
			    high--;
			swap(low, high);
			while(low < high && l->at(low) <= pivotkey)
			    low++;
			swap(low, high);  
		}
		return low;
	}
   
    //快速排序递归函数 
    void QSort(DList *l,int low, int high){
    	int pivot;
    	if(low < high){
    		pivot = Partition(l,low,high);
    		QSort(l,low,pivot-1);
    		QSort(l,pivot+1,high);
		}
	}
	//快速排序
    void QuickSort(){
        QSort(this,0,len-1);	
	}
};

#endif // DLIST_H

调用: main.cpp

#include <iostream>
#include "dlist.h"

int main(int argc, char** argv) {	 
    try { 
    DList list; 
    list.push_back(1);
    list.push_back(9);
    list.push_back(9);
    list.push_back(4);
    list.push_back(0);
    list.push_back(8);
    list.push_back(0);
    list.push_back(1); 
	cout<<"【测试 push_back】 ";   
	list.print();
	 
	DList list2(list); 	
	cout<<"【测试 拷贝构造函数】 "; 
    list2.print(); 
    
    DList list3 = list; 
    cout<<"【测试 运算符重载函数】 ";
    list3.print(); 
	  
	cout<<"【测试 indexOf(4)】 ";  
    cout<<list3.indexOf(4)<<endl;
    
    cout<<"【测试 swap(0,1)】 ";  
    list3.swap(0,1);
    list3.print();
    
    cout<<"【测试 QuickSort】 "; 
	list3.QuickSort(); 
    list3.print(); 
    
    cout<<"【测试 removeAt(4)】 ";  
	list3.removeAt(4);
    list3.print();
    
    cout<<"【测试 clear】 ";  
    list3.clear();
	list3.print(); 
    }
    catch (exception const& ex) {
        cerr << "Exception: " << ex.what() <<endl;
        return -1;
    }
   
    return 0;
}

输出:

在这里插入图片描述

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基于模板的双向循环链表的实现,代码中包含详细注释,可以帮助你更好地理解: ```cpp #include <iostream> using namespace std; // 定义节点结构体 template <typename T> struct Node { T data; Node<T>* prev; Node<T>* next; Node(const T& d, Node<T>* p = nullptr, Node<T>* n = nullptr) : data(d), prev(p), next(n) {} }; // 定义双向循环链表类 template <typename T> class DoubleLinkedList { public: // 构造函数 DoubleLinkedList(); // 复制构造函数 DoubleLinkedList(const DoubleLinkedList& rhs); // 移动构造函数 DoubleLinkedList(DoubleLinkedList&& rhs) noexcept; // 赋值运算符 DoubleLinkedList& operator=(const DoubleLinkedList& rhs); // 移动赋值运算符 DoubleLinkedList& operator=(DoubleLinkedList&& rhs) noexcept; // 析构函数 ~DoubleLinkedList(); // 获取链表长度 int size() const; // 判断链表是否为空 bool empty() const; // 获取第一个节点的数据 T& front(); const T& front() const; // 获取最后一个节点的数据 T& back(); const T& back() const; // 插入数据到链表头部 void push_front(const T& value); // 插入数据到链表尾部 void push_back(const T& value); // 删除第一个节点 void pop_front(); // 删除最后一个节点 void pop_back(); // 在指定位置插入数据 void insert(int pos, const T& value); // 删除指定位置的节点 void erase(int pos); // 清空链表 void clear(); // 打印链表元素 void print() const; private: int m_size; // 链表长度 Node<T>* head; // 头指针 Node<T>* tail; // 尾指针 // 初始化链表 void init(); // 复制链表 void copy(const DoubleLinkedList& rhs); }; // 初始化链表 template <typename T> void DoubleLinkedList<T>::init() { m_size = 0; head = tail = new Node<T>(T(), nullptr, nullptr); // 创建一个头节点 head->prev = tail; // 头节点前驱指向尾节点 head->next = tail; // 头节点后继指向尾节点 } // 复制链表 template <typename T> void DoubleLinkedList<T>::copy(const DoubleLinkedList& rhs) { init(); // 初始化当前链表 Node<T>* p = rhs.head->next; while (p != rhs.tail) { // 遍历rhs链表 push_back(p->data); // 将rhs链表中节点的数据插入到当前链表中 p = p->next; } } // 构造函数 template <typename T> DoubleLinkedList<T>::DoubleLinkedList() { init(); // 初始化链表 } // 复制构造函数 template <typename T> DoubleLinkedList<T>::DoubleLinkedList(const DoubleLinkedList& rhs) { copy(rhs); // 复制链表 } // 移动构造函数 template <typename T> DoubleLinkedList<T>::DoubleLinkedList(DoubleLinkedList&& rhs) noexcept : m_size(rhs.m_size), head(rhs.head), tail(rhs.tail) { rhs.m_size = 0; rhs.head = rhs.tail = nullptr; } // 赋值运算符 template <typename T> DoubleLinkedList<T>& DoubleLinkedList<T>::operator=(const DoubleLinkedList& rhs) { if (this != &rhs) { // 判断是否为自赋值 clear(); // 清空当前链表 copy(rhs); // 复制链表 } return *this; } // 移动赋值运算符 template <typename T> DoubleLinkedList<T>& DoubleLinkedList<T>::operator=(DoubleLinkedList&& rhs) noexcept { if (this != &rhs) { // 判断是否为自赋值 clear(); // 清空当前链表 m_size = rhs.m_size; head = rhs.head; tail = rhs.tail; rhs.m_size = 0; rhs.head = rhs.tail = nullptr; } return *this; } // 析构函数 template <typename T> DoubleLinkedList<T>::~DoubleLinkedList() { clear(); // 清空链表 delete head; // 释放头节点 } // 获取链表长度 template <typename T> int DoubleLinkedList<T>::size() const { return m_size; } // 判断链表是否为空 template <typename T> bool DoubleLinkedList<T>::empty() const { return m_size == 0; } // 获取第一个节点的数据 template <typename T> T& DoubleLinkedList<T>::front() { return head->next->data; } template <typename T> const T& DoubleLinkedList<T>::front() const { return head->next->data; } // 获取最后一个节点的数据 template <typename T> T& DoubleLinkedList<T>::back() { return tail->prev->data; } template <typename T> const T& DoubleLinkedList<T>::back() const { return tail->prev->data; } // 插入数据到链表头部 template <typename T> void DoubleLinkedList<T>::push_front(const T& value) { Node<T>* p = new Node<T>(value, head, head->next); // 创建一个新节点 head->next->prev = p; // 原头节点的后继节点的前驱指向新节点 head->next = p; // 头节点的后继指向新节点 ++m_size; // 链表长度加1 } // 插入数据到链表尾部 template <typename T> void DoubleLinkedList<T>::push_back(const T& value) { Node<T>* p = new Node<T>(value, tail->prev, tail); // 创建一个新节点 tail->prev->next = p; // 原尾节点的前驱节点的后继指向新节点 tail->prev = p; // 尾节点的前驱指向新节点 ++m_size; // 链表长度加1 } // 删除第一个节点 template <typename T> void DoubleLinkedList<T>::pop_front() { if (!empty()) { // 判断链表是否为空 Node<T>* p = head->next; // 暂存头节点的后继节点 head->next = p->next; // 头节点的后继指向第二个节点 p->next->prev = head; // 第二个节点的前驱指向头节点 delete p; // 释放第一个节点的内存空间 --m_size; // 链表长度减1 } } // 删除最后一个节点 template <typename T> void DoubleLinkedList<T>::pop_back() { if (!empty()) { // 判断链表是否为空 Node<T>* p = tail->prev; // 暂存尾节点的前驱节点 tail->prev = p->prev; // 尾节点的前驱指向倒数第二个节点 p->prev->next = tail; // 倒数第二个节点的后继指向尾节点 delete p; // 释放最后一个节点的内存空间 --m_size; // 链表长度减1 } } // 在指定位置插入数据 template <typename T> void DoubleLinkedList<T>::insert(int pos, const T& value) { if (pos >= 0 && pos <= m_size) { // 判断pos是否合法 if (pos == 0) { // 如果pos为0,则插入到链表头部 push_front(value); } else if (pos == m_size) { // 如果pos为m_size,则插入到链表尾部 push_back(value); } else { // 否则在指定位置插入数据 Node<T>* p = head->next; for (int i = 0; i < pos; ++i) { p = p->next; } Node<T>* q = new Node<T>(value, p->prev, p); // 创建一个新节点 p->prev->next = q; // 插入节点的前驱节点的后继指向新节点 p->prev = q; // 插入节点的后继节点的前驱指向新节点 ++m_size; // 链表长度加1 } } } // 删除指定位置的节点 template <typename T> void DoubleLinkedList<T>::erase(int pos) { if (pos >= 0 && pos < m_size) { // 判断pos是否合法 if (pos == 0) { // 如果pos为0,则删除链表头部节点 pop_front(); } else if (pos == m_size - 1) { // 如果pos为m_size-1,则删除链表尾部节点 pop_back(); } else { // 否则删除指定位置的节点 Node<T>* p = head->next; for (int i = 0; i < pos; ++i) { p = p->next; } p->prev->next = p->next; // 待删除节点的前驱节点的后继指向待删除节点的后继节点 p->next->prev = p->prev; // 待删除节点的后继节点的前驱指向待删除节点的前驱节点 delete p; // 释放待删除节点的内存空间 --m_size; // 链表长度减1 } } } // 清空链表 template <typename T> void DoubleLinkedList<T>::clear() { while (!empty()) { // 循环删除链表中的所有节点 pop_front(); } } // 打印链表元素 template <typename T> void DoubleLinkedList<T>::print() const { Node<T>* p = head->next; while (p != tail) { // 遍历链表 cout << p->data << " "; p = p->next; } cout << endl; } ``` 使用示例: ```cpp int main() { DoubleLinkedList<int> list; // 创建一个双向循环链表 list.push_back(1); // 在尾部插入数据1 list.push_back(2); // 在尾部插入数据2 list.push_front(0); // 在头部插入数据0 list.insert(2, 3); // 在第2个位置插入数据3 list.erase(1); // 删除第1个节点 list.print(); // 打印链表元素 return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值