1. 程式人生 > >1、【資料結構】線性結構之單鏈表

1、【資料結構】線性結構之單鏈表

單向連結串列

一、定義:

    單向連結串列(單鏈表)時連結串列的一種,它由節點組成,每個節點都包含下一個節點的指標。

    單鏈表的特點是:節點的連結方向是單向的;相對於陣列來說,單鏈表的的隨機訪問速度較慢,但是單鏈表刪除/新增資料的效率很高。

二、實現:

    單鏈表的實現方式有很多種,常見的有

        (1)帶頭結點的單鏈表

        (2)不帶頭結點的單鏈表

        (3)帶頭節點和尾節點的單鏈表

    (1)和(2)的主要區別是:

        (1)的頭節點是個空節點,其主要作用是指向連結串列的第一個節點,         (2)的頭結點不是空節點,是整個連結串列的第一個節點。

        (3)是一個迴圈連結串列,即連結串列的尾節點指向頭結點;下面會對各種實現方式進行具體的介紹。

三、實現
(1)帶頭結點的單鏈表的C++實現

SList.h

typedef int Type;
//定義節點類
struct Node
{
    Node(const Type x);
    Type data;
    Node *next;
};

class SList
{
public:
    SList();//建構函式
    SList(const SList&s);//拷貝建構函式
    SList &operator=(SList &s);//賦值運算子過載
    ~SList();//解構函式

public:
    //單鏈表的具體操作
    bool isEmpty();
    int length();
    void reverseList();//逆置
    void printList();//列印連結串列
    void Clear();
    //void sortList();//排序
    void pushBack(const Type &data);//在尾部插入一個節點
    void popBack();//刪除尾節點
    void pushFront(Type data);//頭插
    void popFront();//刪除頭節點

private:
    Node *head;
    int len;//連結串列長度
};

SList.cpp

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

using namespace std;
//節點類的建構函式
Node::Node(const Type x)
    :data(x),next(NULL)
{

}
//建構函式
SList::SList()
    :head(NULL),len(0)
{
    head = new Node(NULL);
    head->next = NULL;
}
//拷貝建構函式
SList::SList(const SList &s)
{
    head->next = NULL;
    len = s.len;
    Node *current; //自己連結串列的尾部元素
    Node *sCurrent = s.head->next;//s的第一個元素
    while(sCurrent != NULL)
    {
        for(int i = 1; i <= s.len; i++)
        {
            Node *newNode = new Node(sCurrent->data);

            if(i == 1)
            {
                head->next = newNode;
                current = head->next;
            }
            else
            {
                current->next = newNode;
                current = current->next;
            }
            sCurrent = sCurrent->next;
        }
    }
}
//賦值運算子過載
SList& SList::operator=(SList &s)//推薦寫法
{
    if(this != &s)
    {
        swap(head, s.head);
    }
    return *this;
}

//解構函式
SList::~SList()
{
    Clear();
}
//清空連結串列
void SList::Clear()
{
    Node *current = NULL;
    Node *p = head->next;
    while(p != NULL)
    {
        current = p->next;
        delete p;
        p = current;
    }
    delete current;
    current = NULL;

    delete head;
    p = NULL;
    len = 0;
}

//連結串列尾部插入
void SList::pushBack(const Type &data)
{
    if(head->next == NULL)
    {
        head->next = new Node(data);
        len++;
    }
    else
    {
        Node *p = head->next;
        while(p->next != NULL)
        {
            p = p->next;
        }
        p->next = new Node(data);
        len++;

        p = NULL;
    }
}
//連結串列尾部刪除
void SList::popBack()
{
    if(head->next == NULL)
        cout << "this SList is empty." << endl;
    else
    {
        Node *current;
        Node *p = head->next;
        for(int i = 1; i < len-1; i++)
        {
            p = p->next;
        }
        current = p->next;
        p->next = current->next;
        delete current;
        current = NULL;
        len--;
    }
}
void SList::printList()
{
    if(head->next == NULL)
        cout << "this SList is empty." << endl;
    else
    {
        Node *temp = head->next;
        while(temp != NULL)
        {
            cout << temp->data << " ";
            temp = temp->next;
        }
        cout << endl;
        delete temp;
        temp = NULL;
    }
}

//判斷連結串列是否為空
bool SList::isEmpty()
{
    if(head->next == NULL)
        return true;
    else
        return false;
}

//獲取連結串列長度
int SList::length()
{
    return len;
}

//連結串列逆置
void SList::reverseList()
{
    Node *temp = head->next;
    head->next = NULL;
    if(temp == NULL)
        cout << "this SList is empty." << endl;
    else
    {
        while(temp != NULL)
        {
            Node *p = temp->next;
            temp->next = head->next;
            head->next = temp;
            temp = p;
        }
    }
}

void SList::pushFront(Type data)
{
    if(head->next == NULL)
        head->next = new Node(data);
    else
    {
        Node *temp = new Node(data);
        temp->next = head->next;
        head->next = temp;
    }
}

void SList::popFront()
{
    if(head->next == NULL)
        cout << "this SList is empty." << endl;
    else
    {
        Node *temp = head->next;
        head->next = temp->next;
        delete temp;
    }
}

main.cpp

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

using namespace std;

int main()
{
    SList mylist;

    mylist.pushBack(1);
    mylist.pushBack(2);
    mylist.pushBack(3);
    mylist.printList();

    mylist.popBack();
    mylist.printList();

    mylist.reverseList();
    mylist.printList();

    mylist.pushFront(5);
    mylist.printList();

    mylist.popFront();
    mylist.printList();
    return 0;
}

C++實現單鏈表(不帶頭結點) SList.h

typedef int Type;
//定義節點類
struct Node
{
    Node(const Type x);
    Type data;
    Node *next;
};

class SList
{
public:
    SList();//建構函式
    SList(const SList&s);//拷貝建構函式
    SList &operator=(SList &s);//賦值運算子過載
    ~SList();//解構函式

public:
    //單鏈表的具體操作
    bool isEmpty();
    int length();
    void reverseList();//逆置
    void printList();//列印連結串列
    void Clear();
    //void sortList();//排序
    void pushBack(const Type &data);//在尾部插入一個節點
    void popBack();//刪除尾節點
    void pushFront(Type data);//頭插
    void popFront();//刪除頭節點\

private:
    Node *head;
    int len;//連結串列長度
};

SList.cpp

#include <iostream>
#include <assert.h>
#include "SList.h"

using namespace std;
//節點類的建構函式
Node::Node(const Type x)
    :data(x),next(NULL)
{

}
//建構函式
SList::SList()
    :head(NULL),len(0)
{

}
//拷貝建構函式
SList::SList(const SList &s)
{
    head = NULL;
    len = s.len;
    Node *current; //自己連結串列的尾部元素
    Node *sCurrent = s.head;//s的第一個元素
    while(sCurrent != NULL)
    {
        for(int i = 1; i < s.len; i++)
        {
            Node *newNode = new Node(NULL);
            newNode->data = sCurrent->data;
            newNode->next = NULL;
            if(i ==1)
            {
                head = newNode;
                current = head;
            }
            else
            {
                current->next = newNode;
                current = current->next;
            }
            sCurrent = sCurrent->next;
        }
    }
}
//賦值運算子過載
SList& SList::operator=(SList &s)//賦值運算子過載()
{
    if(this != &s)
    {
        swap(head, s.head);
    }
    return *this;
}

//解構函式
SList::~SList()
{
    Clear();
}
//清空連結串列
void SList::Clear()
{
    Node *current;
    while(head != NULL)
    {
        current = head;
        head = current->next;
        delete current;
    }
    head = NULL;
    len = 0;
}
//尾部插入新節點
void SList::pushBack(const Type &data)
{
    if(head == NULL)
    {
        head = new Node(data);
        len++;
    }
    else
    {
        Node *p = head;
        while(p->next != NULL)
        {
            p = p->next;
        }
        p->next = new Node(data);
        len++;

        p = NULL;
    }
}
//列印連結串列
void SList::printList()
{
    if(head == NULL)
    {
        cout << "this SList is empty ! " << endl;
        return ;
    }
    else
    {
        Node *temp = head;
        while(temp != NULL)
        {
            cout << temp->data << " ";
            temp = temp->next;
        }
        cout << endl;
    }
}
//判斷連結串列是否空
bool SList::isEmpty()
{
    if(head == NULL)
        return true;
    else
        return false;
}
//獲取連結串列長度
int SList::length()
{
    return len;
}
//頭插法逆置矩陣
void SList::reverseList()
{
    Node *current = head;
    head = NULL;
    if(current == NULL)
    {
        cout << "this SList is empty." << endl;
    }
    else
    {
        while(current != NULL)
        {
            Node *nextCurrent = current->next;
            //頭插法連結串列逆置
            current->next = head;//head = NULL
            head = current;
            current = nextCurrent;
        }
    }
}
//刪除尾節點
void SList::popBack()
{
    if(head == NULL)
        cout << "this SList is empty." << endl;
    else
    {
        Node *p = head;
        //找到倒數第二個節點
        for(int i = 1; i < len-1; i++)
        {
            p = p->next;
        }
        Node *current = p->next;
        p->next = current->next;
        delete current;
        len--;
    }
}

//頭部插入
void SList::pushFront(Type Data)
{
    if(head == NULL)
    {
        pushBack(Data);
    }
    else
    {
        Node *temp = head;
        head = new Node(Data);
        head->next = temp;
    }
}

//頭部刪除
void SList::popFront()
{
    if(head == NULL)
        cout << "this SList is empty." << endl;
    else
    {
        Node *temp = head;
        head = temp->next;
        delete temp;
    }
}

main.cpp

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

using namespace std;

int main()
{
    SList myList;
    myList.pushBack(1);
    myList.pushBack(2);
    myList.pushBack(3);
    myList.printList();

    myList.reverseList();
    myList.printList();

    myList.popBack();
    myList.printList();

    myList.pushFront(4);
    myList.printList();

    myList.popFront();
    myList.printList();
    return 0;
}

C++實現單鏈表(帶頭結點和尾結點) SList.h

typedef int Type;
//定義節點類
struct Node
{
    Node(const Type x);
    Type data;
    Node *next;
};

class SList
{
public:
    SList();//建構函式
    SList(const SList&s);//拷貝建構函式
    SList &operator=(SList &s);//賦值運算子過載
    ~SList();//解構函式

public:
    //單鏈表的具體操作
    bool isEmpty();
    int length();
    void reverseList();//逆置
    void printList();//列印連結串列
    void Clear();
    //void sortList();//排序
    void pushBack(const Type &data);//在尾部插入一個節點
    void popBack();//刪除尾節點
    void pushFront(Type data);//頭插
    void popFront();//刪除頭節點\

private:
    Node *head;
    Node *tail;
    int len;//連結串列長度
};

SList.cpp

#include <iostream>
#include <assert.h>
#include "SList.h"

using namespace std;
//節點類的建構函式
Node::Node(const Type x)
    :data(x),next(NULL)
{

}
//建構函式
SList::SList()
    :head(NULL),tail(NULL),len(0)
{

}
//拷貝建構函式
SList::SList(const SList &s)
{
    if(s.head == NULL)
        return;
    Node *temp = s.head;
    do{
        pushBack(temp->data);
        temp = temp->next;
    }while(temp != s.head);
    len = s.len;
}
//賦值運算子過載
SList& SList::operator=(SList &s)//賦值運算子過載()
{
    if(this != &s)
    {
        swap(head, s.head);
        swap(tail, s.tail);
    }
    return *this;
}

//解構函式
SList::~SList()
{
    Clear();
}
//清空連結串列
void SList::Clear()
{
    Node *current = head;
    while(current != tail)
    {
        head = head->next;
        delete current;
        current = head;
    }
    head = NULL;
    tail = NULL;
    len = 0;
}
//尾部插入新節點
void SList::pushBack(const Type &data)
{
    if(head == NULL)
    {
        head = new Node(data);
        tail = head;
        tail->next = head;
    }
    else
    {
        tail->next = new Node(data);
        tail = tail->next;
        tail->next = head;
    }
    len++;
}
//列印連結串列
void SList::printList()
{
    if(head == NULL)
    {
        cout << "this SList is empty ! " << endl;
        return ;
    }
    else
    {
        Node *temp = head;
       do{
            cout << temp->data << " ";
            temp = temp->next;
       }while(temp != head);
        cout << endl;
    }
}
//判斷連結串列是否空
bool SList::isEmpty()
{
    if(head == NULL)
        return true;
    else
        return false;
}
//獲取連結串列長度
int SList::length()
{
    return len;
}
//頭插法逆置矩陣
void SList::reverseList()
{
    if(head == NULL || head->next == tail)
    {
        return ;
    }
    tail = new Node(head->data);
    Node *begin = NULL;
    Node *temp = tail;
    while(len--)
    {
        Node *del = head;
        head = head->next;
        delete del;
        begin = new Node(head->data);
        begin->next = temp;
        tail->next = begin;
        temp = begin;
    }
    head = begin;
}
//刪除尾節點
void SList::popBack()
{
    if(head == NULL)
        cout << "this SList is empty." << endl;
    else if(head == tail)
    {
        delete head;
        head = NULL;
        tail = NULL;
    }
    else
    {
        Node *current = head;
        while(current->next != tail)
        {
            current = current->next;
        }
        delete tail;
        tail = current;
        tail->next = head;
    }
}

//頭部插入
void SList::pushFront(Type Data)
{
    if(head == NULL)
    {
        pushBack(Data);
    }
    else
    {
        Node *temp = head;
        head = new Node(Data);
        head->next = temp;
        tail->next = head;
    }
}

//頭部刪除
void SList::popFront()
{
    if(head == NULL)
    {
        cout << "this SList is empty." << endl;
        return ;
    }
    else
    {
        Node *temp = head;
        head = head->next;
        tail->next = head;
        delete temp;
    }
}

main.cpp

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

using namespace std;

int main()
{
    SList myList;
    myList.pushBack(1);
    myList.pushBack(2);
    myList.pushBack(3);
    myList.printList();

    myList.reverseList();
    myList.printList();

    myList.popBack();
    myList.printList();

    myList.pushFront(4);
    myList.printList();

    myList.popFront();
    myList.printList();
    return 0;
}