单链表的基本操作(C++实现)

来源:互联网 发布:不用网络的手机电视 编辑:程序博客网 时间:2024/05/29 00:34

什么是链表

链表属于线性表的一种,所有的数据按线性顺序排列。还有一种线性表是数组,这种数据结构各有各的优点,数组可以随机访问,并且可以根据下标在O(1)的时间内访问数据,而链表不可以随机访问,链表的顺序是由各个对象里的指针决定的。数组在内存中是顺序存储,所以会占一大部分连续的存储空间,而链表可以分散存储,之间的联系靠指针指向就可以,方便使用内存的零碎的空间。在增删方面,数组也是不理想的,每次增删都要移动数据,最坏的情况下是O(n-1),而链表则可以修改指针的指向在O(1)的时间内就可以完成增删,非常方便。
这里写图片描述

链表的节点一般包括数据域和指针域
头节点的数据域一般存放链表的整体信息,比如链表的长度信息。

需求

编写链表数据结构,要包括基本的增删改查,此次我用c++实现,既接近底层,又可以用类的思想,更好理解面向对象编程。

代码实现

首先新建一个头文件,用于声明要用到结构体的定义和类Linklist的定义。head.h

#include <iostream>using namespace std;struct Node {    int value;    Node* next;    Node(int num) :value(num),next(NULL) {};    Node() {};};class LinkList {public:    void create();           //初始化    void insertHead(Node*);  //头插法    void insertTail(Node*);  //尾插法    Node* findByIndex(int);  //根据索引查找节点,并返回节点的指针,注意0返回头节点    Node* findByValue(int);  //根据值查找节点,并返回节点的指针,注意0返回头节点    int  getLength();        //获取链表的长度    void deleteByIndex(int); //根据索引删除节点    void deleteByValueOnce(int); //根据节点值删除第一个节点    void deleteByValueAll(int);//根据节点值删除所有节点    void editByIndex(int,int);   //根据索引修改节点的值    void print();private:    Node* head;        //头节点指针,value用于存放链表的长度};

LinkList实现的cpp文件

#include "head.h"void LinkList::create() {    head = new Node();    head->next = NULL;    head->value = 0;}void LinkList::insertHead(Node* p) {    p->next = head->next;    head->next = p;    head->value++;}void LinkList::insertTail(Node* p) {    Node* tail = findByIndex(head->value);    if (tail == NULL)        insertHead(p);    else {        p->next = tail->next;        tail->next = p;    }    head->value++;}Node* LinkList::findByIndex(int index){    Node* p = head;    int i = 0;    if (index<0||index >getLength()) {        cout << "索引非法!" << endl;        return NULL;    }    while (p) {        if (i == index)             return p;        else {            p = p->next;            i++;        }    }    return NULL;}Node* LinkList::findByValue(int value) {    Node* p = head->next;    for (;p;p=p->next){        if (p->value == value)            return p;    }    return NULL;}int LinkList::getLength() {    return head->value;}void LinkList::deleteByIndex(int index) {    if (index == 0) {        cout << "不能删除头节点!" << endl;        return;    }    Node* p = findByIndex(index);    if (!p) {        cout << "删除失败!" << endl;        return;    }    else {        Node* q = findByIndex(index - 1);        q->next = p->next;        head->value--;        delete p;    }}void LinkList::deleteByValueOnce(int value) {    Node* p = head->next;    Node* q = head;    bool flag = false;    for (;p;p = p->next,q=q->next) {        if (p->value == value) {            q->next = p->next;            delete p;            flag = true;            head->value--;            break;        }    }    if (!flag) {        cout << "链表中不存在值为:" << value << "的节点" << endl;    }}void LinkList::deleteByValueAll(int value) {    Node* p = head->next;    Node* q = head;    bool flag = false;    while(p){        if (p->value == value) {            q->next = p->next;            Node* temp = p;            p = p->next; //此处q不动,留给你们思考,不会再留言,嘻嘻            delete temp;            head->value--;            flag = true;        }        else {            p = p->next;            q = q->next;        }    }    if (!flag) {        cout << "链表中不存在值为:" << value << "的节点" << endl;    }}void LinkList::editByIndex(int index,int value) {    if (index == 0) {        cout << "不能修改头节点!" << endl;        return;    }    Node* p = findByIndex(index);    if (!p) {        cout << "修改失败!" << endl;        return;    }    else {        p->value = value;    }}void LinkList::print() {    for (Node* p = head->next;p;p = p->next) {        cout << p->value << " ";    }    cout << endl;}

测试函数

main.cpp

#include"head.h"void printAnswer(LinkList linklist) {    linklist.print();    cout << "当前长度:";    cout << linklist.getLength() << endl;}int main() {    int n;    cout << "请输入节点个数:";    cin >> n;    LinkList linklist;    linklist.create();    int num;    while (n--) {        cin >> num;        linklist.insertHead(new Node(num));    }    cout << "头插法结果:";    printAnswer(linklist);    cout << "尾插一个数:";    cin >> num;    linklist.insertTail(new Node(num));    cout << "尾插法结果:";    printAnswer(linklist);    cout << "想删除第几个:";    cin >> num;    linklist.deleteByIndex(num);    cout << "删除结果:";    printAnswer(linklist);    cout << "输入你想删除值为多少的节点(只删除首个):";    cin >> num;    linklist.deleteByValueOnce(num);    cout << "删除结果:";    printAnswer(linklist);    cout << "输入你想删除值为多少的节点(所有的):";    cin >> num;    linklist.deleteByValueAll(num);    cout << "删除结果:";    printAnswer(linklist);    int replace;    cout << "输入你想修改第几个节点并改成值为多少:";    cin >> num >> replace;    linklist.editByIndex(num, replace);    cout << "修改结果:";    printAnswer(linklist);}

测试结果

这里写图片描述

总结

链表的操作有很多,以后遇见了再进行补充。

原创粉丝点击