线性表之链式存储结构

一. 引言
链式存储结构,又叫链接存储结构。在计算机中用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的).链式存储结构相对于顺序存储结构而言存储密度小,插入、删除灵活,逻辑上相邻的节点物理上不必相邻,查找结点时链式存储要比顺序存储慢。下面介绍链式存储结构的一种简单形式单链表结构及其c++实现。

二. 单链表的结构及基本操作
单链表的每一个单元成为结点,每个结点包含数据域和指针域,数据域用于存放数据data,指针域用于存放指向下一个结点的指针next。每个单链表必然存在一个头指针head,头指针用于指向头结点,头指针是单链表存在的必要条件。通常头结点的数据域不存放任何信息或用于存放链表长度,指针域用于指向下一个结点。如果头结点的指针域的指针指向的下一个结点为空,则该链表为空链表。非空链表的最后一个结点的指针域指针指向NULL。
1. 基本结构
1) 空链表
这里写图片描述

2)非空链表
这里写图片描述

2. 基本操作

1)单链表的头结点后插入结点操作

这里写图片描述

2)单链表尾部插入结点操作

单链表的尾部结点插入操作的时间复杂度为O(n),因为首先要构造指针遍历单链表的所有结点,找到尾结点,然后在其后面插入结点。

这里写图片描述

3)单链表中间某位置插入结点

例如,链表的数据为a, b, c, e,我们希望在e的前面插入d元素,基本操作如下图所示:

这里写图片描述

4)链表的反转操作

这里写图片描述

5)链表替换某结点的值

遍历结点找到对应结点然后替换。

6)删除链表某结点

这里写图片描述

7)打印链表内容

3. C++代码

类代码:

#include<iostream>
using namespace std;

template<typename T>
class LinkList{
public:
    LinkList(){ init(); };
    LinkList(const LinkList &rhs);
    ~LinkList();
    void InsertHead(const T& v);
    void InsertTail(const T& v);
    void Insert(const T& d, const T& v);
    void Erase(const T& d);
    void Update(const T& d, const T& v);
    void Reverse();
    void Printer();
private:
    struct Node{
        T data;
        Node* next;
        Node(const T& d = T(), Node* n = NULL) :data(d), next(n){}
    };
    Node* head;                    //定义头节点
    int length;
    void init(){                   //初始化链表
        length = 0;
        head = new Node;
    }

    Node* Find(const T& d){
        Node* p = head;
        while (p){
            if (p->next->data == d)
                break;
            p = p->next;
        }
        return p;
    }
};

template<typename T>
LinkList<T>::LinkList(const LinkList &rhs){
    init();
    *this = rhs;
}

template<typename T>
LinkList<T>::~LinkList(){
    Node* p = NULL;
    while (head->next != NULL){
        p = head->next;
        head->next = p->next;
        delete p;
    }
}

template<typename T>
void LinkList<T>::Insert(const T& d, const T& v){
    Node* p = Find(d);
    Node* q = new Node(v);
    q->next = p->next;
    p->next = q;
}

template<typename T>
void LinkList<T>::Erase(const T& d){
    Node* p = Find(d);
    Node* q = p->next;
    p->next = p->next->next;
    delete q;
}

template<typename T>
void LinkList<T>::Update(const T& d, const T& v){
    Node* p = Find(d);
    p->next->data = v;
}

template<typename T>
void LinkList<T>::InsertHead(const T& v){
    Node* p = new Node(v);
    p->next = head->next;
    head->next = p;
}

template<typename T>
void LinkList<T>::InsertTail(const T& v){
    Node* p = head;
    Node* q = new Node(v);
    while (p->next)
        p = p->next; 
    p->next = q;
    q->next = NULL;
}

template<typename T>
void LinkList<T>::Printer(){
    for (Node* p = head->next; p; p=p->next){
        cout << p->data << " ";
    }
    cout << endl;
}

template<typename T>
void LinkList<T>::Reverse(){
    Node* p = head->next;
    Node* q = head->next->next;
    Node* m = head->next->next->next;
    head->next->next = NULL;
    while (m){
        q->next = p;
        p = q;
        q = m;
        m = m->next;
    }
    q->next = p;
    head->next = q;
}

测试代码:

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

using namespace std;

int main()
{
    LinkList<int> List;
    List.InsertHead(1);
    List.InsertHead(2);
    List.InsertHead(4);
    List.InsertHead(6);
    List.Printer();
    List.Reverse();
    List.Printer();
    List.InsertTail(7);
    List.Printer();
    List.Insert(4, 3);
    List.Insert(6, 5);
    List.Printer();
    List.Erase(7);
    List.Printer();
    List.Update(3, 7);
    List.Printer();
    LinkList<int> List1 = List;
    List1.Printer();
    return 0;
}

测试结果:

这里写图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值