1. 程式人生 > >數據結構算法——鏈表的各種操作

數據結構算法——鏈表的各種操作

無法 input 叠代 error iostream list() tmp 博客 遇到

時隔已久,一直沒更新博客,感覺很愧疚呀。

先貼上所有的代碼。這個是用C++寫的

#include "stdafx.h"

//Author:Albert
//Date: 2018.10.28

#include<iostream>
using namespace std;

typedef int datatype;
class Node
{
public:
    int data;
    Node *next;
};

class linkList
{
public:
    linkList();//初始化一個單鏈表
    ~linkList();//銷毀一個單鏈表
    bool creatLinkListByInput(int
n);//通過控制臺輸入新建一個長度為n的單鏈表 void dispLinkList();//把鏈表裏儲存的數據都顯示出來 int getLength(); void insertNodetoEnd(datatype data); void insertNode(datatype data, int n);//在第n個數據後插入一個數據data void DeleteNode(int n);//刪除第n個節點 void Reverse(); private: Node * head; }; linkList::linkList() { head
= new Node; head->data = 0; head->next = NULL; } linkList::~linkList() { delete head; } bool linkList::creatLinkListByInput(int n) { Node *pnew, *ptemp; ptemp = head; if (n < 0) { cout << "error" << endl; return false; } for (int i = 0;i < n;i++) { pnew
= new Node; cout << "請輸入第" << i + 1 << "個值:"; cin >> pnew->data; pnew->next = NULL; ptemp->next = pnew; ptemp = pnew; } return true; } void linkList::dispLinkList() { Node *p; p = head; if (p!=NULL) { while (p->next!=NULL) { p = p->next; cout << p->data << endl; } } else { cout << "這是一個空鏈表" << endl; } } int linkList::getLength() { int n=0; Node *p; p = head; while (p->next!=NULL) { n++; p = p->next; } return n; } void linkList::insertNodetoEnd(datatype data) { Node *pnew=new Node; pnew->data = data; pnew->next = NULL; Node *p=head; while (p->next != NULL) { p = p->next; } p->next = pnew; } void linkList::insertNode(datatype data, int n) { Node *p = head; Node *pnew = new Node; for (int i = 0;i < n;i++) { p = p->next; } //此時p指向的是第n個數據 pnew->data = data; pnew->next = p->next; p->next = pnew; } void linkList::DeleteNode(int n) { Node *p = head; Node *ppre = new Node; for (int i = 0;i < n;i++) { ppre = p; p = p->next; } //ppre是要刪除的節點的前一個節點 ppre->next = p->next; delete p; } void linkList::Reverse() { Node *plast = head->next; Node *p = plast->next; Node *ptmp = new Node; plast->next = NULL; while (p->next != NULL) { ptmp = p; p = p->next; ptmp->next = plast; plast= ptmp; } p->next = plast; head->next = p; } int main() { linkList a; //新建一個長度為3的單鏈表 a.creatLinkListByInput(3); a.dispLinkList(); cout << "鏈表長度為:" << a.getLength() << endl; cout << "在尾部插入一個1:" << endl; a.insertNodetoEnd(1); a.dispLinkList(); cout << "鏈表長度為:" << a.getLength() << endl; cout << "在第2個數據後插入1:" << endl; a.insertNode(1,2); a.dispLinkList(); cout << "鏈表長度為:" << a.getLength() << endl; cout << "刪除第4個數據" << endl; a.DeleteNode(4); a.dispLinkList(); cout << "鏈表長度為:" << a.getLength() << endl; cout << "將鏈表逆置" << endl; a.Reverse(); a.dispLinkList(); return 0; }

1、新建一個單鏈表

bool linkList::creatLinkListByInput(int n)
{
    Node *pnew, *ptemp;
    ptemp = head;
    if (n < 0) { cout << "error" << endl; return false; }
    for (int i = 0;i < n;i++)
    {
        pnew = new Node;
        cout << "請輸入第" << i + 1 << "個值:";
        cin >> pnew->data;
        pnew->next = NULL;
        ptemp->next = pnew;
        ptemp = pnew;
    }
    return true;
}

這個代碼還是我看了別人的之後才寫的。在控制臺輸入一系列數據,返回是否新建成功。

其中最關鍵的一處就是定義一個head節點。這個節點不儲存數據,head->next才是第一個儲存的數據。

這樣的話就比較好寫循環裏的內容了,後面的調用也很方便。

用圖畫一下就很容易理解了。

技術分享圖片

顯示整個鏈表數據,得到鏈表長度什麽的,不用多說啦。直接遍歷就行。

2、插入節點。

void linkList::insertNode(datatype data, int n)
{
Node *p = head;
Node *pnew = new Node;
for (int i = 0;i < n;i++)
{
p = p->next;
}
//此時p指向的是第n個數據
pnew->data = data;
pnew->next = p->next;
p->next = pnew;
}

先遍歷到到第n個節點

然後

技術分享圖片

3、刪除一個節點

void linkList::DeleteNode(int n)
{
    Node *p = head;
    Node *ppre = new Node;
    for (int i = 0;i < n;i++)
    {
        ppre = p;
        p = p->next;
    }
    //ppre是要刪除的節點的前一個節點
    ppre->next = p->next;
    delete p;
}

把它畫出來就是

技術分享圖片

4、單鏈表的逆置

void linkList::Reverse()
{
    
    Node *plast = head->next;
    Node *p = plast->next;
    Node *ptmp = new Node;
    plast->next = NULL;
    while (p->next != NULL)
    {
        ptmp = p;
        p = p->next;
        ptmp->next = plast;
        plast= ptmp;
    }
    p->next = plast;
    head->next = p;
}

技術分享圖片

這裏ptmp的作用就是為了防止p->next=plast從而導致無法往下遍歷。

我見還有一種用ppre,p,pnex三個指針的。思想跟這個差不多。

感覺自己菜的要死,只能從頭再開始學啦。

還有幾個問題

鏈表中環的檢測:用的快慢指針的思想。

兩個有序鏈表的合並:遍歷,主要是別讓指針指亂了。

刪除鏈表倒數第n個節點。如果鏈表長度知道,就很簡單了,轉化為整數就好。如果長度不知道,我覺得,就用叠代可以有。

求鏈表中的中間節點,用快慢針呀。

這幾個問題我沒時間一個一個的寫啦。以後遇到了在一個一個的寫。

此外還有循環鏈表和雙向鏈表,他們都各有千秋,懂的單鏈表,這都很簡單了。

數據結構算法——鏈表的各種操作