數據結構之單向鏈表的實現【C++】

本科沒有學習過數據結構,之前也只是泛泛的看看鏈表的原理,並沒有實際編寫,昨天就係統的將鏈表的各項功能給實現了下,其中包括:移除,插入,更改,清空,打印,鏈表反轉等功能;其中,鏈表的反轉這在《劍指offer》以及其他面試中經常會被問到的問題;同時,對鏈表的熟悉可以爲後期的隊列以及棧等的編寫提供基礎,所以還是很有必要從頭將鏈表進行弄明白。

  1. 首先建立List.h文件,爲了和STL中的list進行區分,所以才用大寫表示:
#ifndef _LIST_H_
#define _LIST_H_

#include<iostream>
#include<string>

using namespace std;

struct Info
{
    string name;
    int id;
};

struct Node
{
    Info val;
    Node * next;
    Node(Info x):val(x),next(NULL){};
};

class List
{
public:
    List();
    ~List();

    void ListHead(Info val); //插入鏈表頭

    void Insert(Info val,int pos); //在pos位置插入信息val
    void Insert(Info val);//默認在鏈表的最後添加數據
    int Find(Info val);//查找val,並返回val前一個節點的指針

    void Remove(Info val);//移除val

    void Update(Info val,Info val1);//更新val的值爲val1

    void Print();//打印鏈表

    void erase();//清空鏈表

    void Reverse();//鏈表反轉


private:
    Node * head;//一個鏈表的頭指針
    int length;//鏈表的長度
};
#endif

2、然後建立List.cpp文件

#include"List.h"

List::List()
{
    head = NULL;
    length = 0;
}

List::~List()
{
    Node * temp = head;
    for(int i = 0;i < length;i++)
    {
        delete temp;
        temp = temp->next;
    }
}
//創建一個鏈表頭

void List::ListHead(Info val)
{
    Insert(val,0);
}

//在鏈表中pos的位置插入數據
void List::Insert(Info val,int pos)
{
    if(pos < 0)
        cout<<"Error:pos must be integer!";
    Node *temp = head;
    Node *node = new Node(val);

    int index = 1;

    if(pos == 0)
    {
        node->next = temp;
        head = node;
        length++;
        return;
    }
    while(temp!=NULL && index < pos)
    {
        temp = temp->next;
        index++;
    }
    if(temp == NULL)
    {
        cout<<"Error:Insert failed!"<<endl;
        return;
    }
    node->next = temp->next;
    temp->next = node;
    length++;
}

//默認在鏈表的末尾添加數據

void List::Insert(Info val) 
{
    Node *temp = head;
    Node *p;
    Node* node = new Node(val);

    while(temp->next!=NULL)
    {
        temp = temp->next;
    }
    node->next = temp->next;
    temp->next = node;
    length++;
}
//在鏈表中查找val
int List::Find(Info val)
{
    Node* temp = head;
    int index = 1;
    for(;temp;temp = temp->next)
    {
        if(temp->val.id == val.id && temp->val.name == val.name)
            return index;
        index++;
    }
    return -1;
}
//刪除val值
void List::Remove(Info val)
{
    int pos = Find(val);
    if(pos == -1)
        cout<<"Error:Remove failed!"<<endl;
    if(pos == 1)
    {
        head = head->next;
        length--;
        return;
    }

    int index = 2;
    Node* temp = head;
    while(index<pos)
    {
        temp = temp->next;
        index++;
    }
    temp->next = temp->next->next;
    length--;
}
//打印鏈表
void List::Print()
{
    Node* temp = head;
    if(temp == NULL)
    {
        cout<<"Error:print failed!"<<endl;
        return;
    }
    while(temp!=NULL)
    {
        cout<<temp->val.name<<"<***>"<<temp->val.id<<endl;
        temp = temp->next;
    }
}

//鏈表反轉
void List::Reverse()
{
    if(head==NULL)
        return;
    Node *curNode=head,*nextNode=head->next,*temp;
    while(nextNode!=NULL)
    {
        temp=nextNode->next;
        nextNode->next=curNode;
        curNode=nextNode;
        nextNode=temp;
    }
    head->next=NULL;
    head=curNode;
}
//清空鏈表

void List::erase()
{
    Node* temp = head;

    while(temp)
    {
        Node* p = temp->next;
        //temp = temp->next;
        delete temp;
        temp = p;
        head = temp;
        length--;
    }
}

3、最後就是進行test.cpp文件的編寫進行測試程序!

#include"List.h"

int main(int argc,char** argv)
{
    system("color 3F");
    List temp;

    Info val1,val2,val3,val4,val5,val6;
    val1.id = 1;val1.name = "Wang";val2.id = 2;val2.name = "Chao";val3.id = 3;val3.name = "long";
    val4.id = 4;val4.name = "Kong";val5.id = 5;val5.name = "zhi";val6.id = 6;val6.name = "shi";
    cout<<"Listhead test"<<endl;
    temp.ListHead(val1);
    temp.Print();
    temp.Insert(val2,2);
    temp.Print();
    temp.Insert(val2,1);
    temp.Print();
    temp.Insert(val3,2);
    temp.Print();
    cout<<"Remove test!"<<endl;
    temp.Remove(val2);
    temp.Print();

    cout<<"<**************************>"<<endl;
    temp.ListHead(val2);
    temp.Print();

    cout<<"*************************Last******************"<<endl;
    temp.Insert(val4);
    //temp.Print();
    temp.Insert(val5);
    temp.Insert(val6);
    temp.Print();
    cout<<"*************************Remove**********************"<<endl;
    temp.Remove(val5);
    temp.Print();
    cout<<"<************************Reverse*********************>"<<endl;
    temp.Reverse();
    temp.Print();

    cout<<"***********************erase******************"<<endl;
    temp.erase();
    temp.Print();
    system("pause");
    return 0;
}

4、總結
之前都是覺得數據結構特別的難,這次爲了提升自己的算法能力以及代碼的Coding能力,決定再花點時間將《數據結構和算法分析》好好學習一下,平時都是直接調用STL標準庫中現成的API函數,沒什麼感覺,通過對數據結構的學習,可以讓我們從底層的原理實現進行更深層次的瞭解!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章