自己实现c++ list模板类,亲测可用

双向链表模板类

dlist.h

#ifndef DLIST_H
#define DLIST_H
#include <iostream>
#include <string>
#include <stdexcept>
using namespace std;

template<typename T> 
class DList
{
	struct node{
    T data;
    node* next;
    node* prev;
    };
    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(T 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;
    }
    
    //取出节点(按下标) 
    T 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(T _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){
		T vi = at(i);
		T 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(int low, int high){
		T pivotkey;
		pivotkey = at(low); //用子表的第一个记录作为枢轴记录 
		while(low < high){
			while(low < high && at(high) >= pivotkey)
			    high--;
			swap(low, high);
			while(low < high && at(low) <= pivotkey)
			    low++;
			swap(low, high);  
		}
		return low;
	}
    
    //快速排序递归函数 
    void QSort(int low, int high){
    	int pivot;
    	if(low < high){
    		pivot = Partition(low,high);
    		QSort(low,pivot-1);
    		QSort(pivot+1,high);
		}
	}
	//快速排序
    void QuickSort(){
        QSort(0,len-1);	
	}

};

#endif // DLIST_H

测试类型为 DList< std::string >

main.cpp

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

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char** argv) {	 
    try { 
    DList<string> list; 
    list.push_back("a");
    list.push_back("b");
    list.push_back("c");
    list.push_back("d");
    list.push_back("e");
    list.push_back("f");
    list.push_back("g");
    list.push_back("h"); 
	cout<<"【测试 push_back】 ";   
	list.print();
	 
	DList<string> list2(list); 	
	cout<<"【测试 拷贝构造函数】 "; 
    list2.print(); 
    
    DList<string> list3 = list; 
    cout<<"【测试 运算符重载函数】 ";
    list3.print(); 
	  
	cout<<"【测试 indexOf()】 ";  
    cout<<list3.indexOf("c")<<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;
}

运行结果

在这里插入图片描述

面向对象程序设计课程作业 1. 请创建一个数据类型为T的链表类模板List实现以下成员函数: 1) 默认构造函数List(),将该链表初始化为一个空链表(10分) 2) 拷贝构造函数List(const List& list),根据一个给定的链表构造当前链表(10分) 3) 析构函数~List(),释放链表中的所有节点(10分) 4) Push_back(T e)函数,往链表最末尾插入一个元素为e的节点(10分) 5) operator<<()友元函数,将链表的所有元素按顺序输出(10分) 6) operator=()函数,实现两个链表的赋值操作(10分) 7) operator+()函数,实现两个链表的连接,A=B+C(10分) 2. 请编写main函数,测试该类模板的正确性: 1) 用List模板定义一个List类型的模板类对象int_listB,从键盘读入m个整数,调用Push_back函数将这m个整数依次插入到该链表中;(4分) 2) 用List模板定义一个List类型的模板类对象int_listC,从键盘读入n个整数,调用Push_back函数将这n个整数依次插入到该链表中;(4分) 3) 用List模板定义一个List类型的模板类对象int_listA,调用List的成员函数实现A = B + C;(4分) 4) 用cout直接输出int_listA的所有元素(3分) 5) 用List模板定义List类型的模板类对象double_listA, double_listB, double_listC,重复上述操作。(15分) 3. 输入输出样例: 1) 输入样例 4 12 23 34 45 3 56 67 78 3 1.2 2.3 3.4 4 4.5 5.6 6.7 7.8 2) 输出样例 12 23 34 45 56 67 78 1.2 2.3 3.4 4.5 5.6 6.7 7.8
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值