1. 程式人生 > >c++——雙向迴圈連結串列常見操作

c++——雙向迴圈連結串列常見操作

雙向迴圈連結串列示意圖:
這裡寫圖片描述

程式碼:

#ifndef __LIST_H__
#define __LIST_H__
#include <stdio.h>
#include<iostream>
#include<assert.h>
using namespace std;

 class Listnode
{
public:
    int  _data;
     Listnode * prev;  //前續指標
     Listnode* next;  //後續指標
     Listnode(Listnode* _next = NULL,Listnode*_prev = NULL)
        : next(_next)
        , prev(_prev)
    {}
     Listnode(const
int data, Listnode* _next = NULL, Listnode*_prev = NULL) :_data(data) , prev(_prev) , next(_next) { } void Setdata(int data) { this->_data = data; } }; class List :public Listnode { public: List();//建構函式 ~List();//解構函式 bool
Empty() // 清空 { return this->size == 0; } int sizelist() { return this->size; } void pushfront(const int& data); //頭插 void pushback(const int& data); //尾插 void push_val(const int& data, int pos); //任意位置插入 void popfront(); //頭刪
void popback();//尾刪 void pop_val(int pos);//任意位置刪除 Listnode* findnode(int pos);//指定位置查詢 void reserse();//連結串列的逆置 void sortlist();//連結串列排序 void printlist(); private: Listnode* head; //頭指標 Listnode* tail; //尾指標 int size; }; int Getpushfront(); //異常警告 int Getpush_val(); int Getpopfront(); int Getpop_val(); Listnode* Condata(const int& data); #endif
#include "list.h"

Listnode* Condata(const int& data)//構造一個新的節點
{
    Listnode*newnode = new Listnode(data);
    if (newnode == NULL)
    throw Getpushfront();  //丟擲異常
    return newnode;

}
Listnode* List::findnode(int pos)//得到pos位置的節點
{
    Listnode* tempnode = head->next;
    for (int i = 1; i < pos; i++) 
    {
        tempnode = tempnode->next;
    }
    return tempnode;
}
List::List()//建構函式構造頭結點
{
    head = tail = new Listnode;
    head->next = tail;
    tail->prev = head;
    tail->next = head;
    head->prev = tail;
    size = 0;
}
List::~List()
{
    Listnode*pdel;
    Listnode*ptemp;
    pdel = head->next;  //找到第一個節點
    while (pdel != head)  //迴圈頭刪
    {
        ptemp = pdel->next;//定義兩個指標變數 更好釋放
        head->next = ptemp;
        ptemp->prev = head;

        //head->next = pdel->next      一個變數釋放
        //pdel->next->prev = head
        delete pdel;
        pdel = ptemp;   
    }
    delete head;

}
void List::pushfront(const int& data)//頭插
{
    Listnode* newnode = Condata(data);

    if (size == 0)    //本來沒有節點
    {
        newnode->next = tail;
        tail->prev = newnode;
        head->next = newnode;
        newnode->prev = head;
        size++;  
        return ;
    }
    newnode->next = head->next;
    head->next = newnode;
    newnode->next->prev = newnode;
    newnode->prev = head;
    size++;
}
void List::pushback(const int& data)   //尾插
{
    Listnode* newnode = Condata(data);
    if (size == 0)      
    {
        pushfront(data);  //
        return;
    }
    tail->prev->next = newnode;
    newnode->prev = tail->prev;
    newnode->next = tail;
    tail->prev = newnode;
    size++;
}

void List::push_val(const int& data, int pos) //任意位置插入
{
    Listnode* newnode = Condata(data);
    if (pos>(size+1))
    {
        throw Getpush_val();//丟擲異常
        return;
    }
    if ( (pos==1)||(pos == (size + 1)))   //頭插或尾插
    {
        if (pos== 1)
            List::pushfront(data);
        else
        List::pushback(data);
        return;
    }
    Listnode* tempnode = findnode(pos);//找到這個位置的節點
    newnode->next = tempnode;              //插入操作
    tempnode->prev->next = newnode;
    newnode->prev = tempnode;
    tempnode->prev = newnode;
    /*Listnode* _next =tempnode;    //定義兩個變數進行插入操作
    Listnode* _prev = tempnode->prev;
    _prev->next = newnode;
    newnode->next = _next;
    newnode->prev = _prev;
    _next->prev = newnode;
    */
    size++;
}
void List::popfront() //頭刪
{
    if (size == 0)
    {
        throw  Getpopfront();
        return;
    }
    Listnode* tempnode = head->next;
    head->next = head->next->next;
    delete(tempnode);
    tempnode = NULL;
    size--;
}
void List::popback()//尾刪
{
    Listnode* tempnode = tail->prev;
    tempnode->prev->next = tail;
    tail->prev = tempnode->prev;
    delete(tempnode);
    tempnode = NULL;
        size--;
}
void List::printlist()   //列印連結串列
{
    Listnode*tempnode = head->next;
    if (size == 0)
    {
        cout << "連結串列為空" << endl;
        return;
    }
    for (int i =0;i<size;i++)
    {
        printf("%2d " ,tempnode->_data);
        tempnode = tempnode->next;
    }
    printf("\n");
}
void List::pop_val(int pos)//任意位置刪除
{
    if (pos<0 || pos>size)
        throw Getpop_val();  //丟擲異常
    if (pos == 1 || pos == size)
        return pos == 1 ? List::popfront() : List::popback();
    Listnode* tempnode = findnode(pos);
    tempnode->prev->next = tempnode->next;
    tempnode->next->prev = tempnode->prev;
    delete(tempnode);
    tempnode = NULL;
    size--;
}

void List::reserse()  //逆置
{
    Listnode* left = head->next;
    Listnode* right = tail->prev;
    while (left != right)
    {
        int data = left->_data;
        left->_data = right->_data;
        right->_data = data;
        left = left->next;
        right = right->prev;
    }   
}
void List::sortlist ()  //排序
{ 
    Listnode*i_tempnode = head->next;
    for (int i = 0; i < size; i++)
    {
        Listnode* j_tempnode = i_tempnode->next;
        for (int j = 0; j < size - i - 1; j++)
        {
            if (i_tempnode->_data < j_tempnode->_data)
            {
                int data = j_tempnode->_data;
                j_tempnode->_data = i_tempnode->_data;
                i_tempnode->_data = data;

            }
            j_tempnode = j_tempnode->next;
        }
        i_tempnode = i_tempnode->next;
    }
}




int Getpushfront()  
{
    cout << "開闢節點失敗" << endl;
    return  0;
}
int Getpush_val()
{
    cout << "任意插入位置非法" << endl;
    return 0;
}
int Getpopfront()
{
    cout << "連結串列為空,刪除節點失敗" << endl;
    return 0;
}
int Getpop_val()
{
    cout << "刪除位置不合法" << endl;
    return  0;
}

測試程式碼:

#include "list.h"
int main()
{
    List list;
    list.pushfront(5);
    list.pushfront(4);
    /*list.pushfront(3);
    list.pushfront(2);
    list.pushfront(1);
    list.pushback(9);
    list.pushback(8);
    list.pushback(7);*/
    list.pushback(6);
    /*list.printlist();
    list.push_val(11, 4);
    list.push_val(11, 1);
    list.printlist();*/
    ///*list.push_val(11, 30);*/
    //list.printlist();
    //list.popfront();
    //list.printlist();
    //list.popback();
    //list.printlist();
    //list.pop_val(1);
    //list.printlist();
    list.pushback(9);
    list.pushback(1);


    list.printlist();
    /*list.reserse();
    list.printlist();*/
    list.sortlist();
    list.printlist();
return 0;
}