数据结构--链表

数据结构–链表

链表的定义

a)如果结构体成员变量中有指向同类节点的指针变量,那么就能够将一个个的结构具体的变串连起来,这样的一系列节点形象上像一条链子,我们称之为链表。
b)每个节点都是有2部分组成:数据区+地址区(指向自身结构体的指针变量)
c)其中指向自身类型节点的指针,我们称之为地址域。
d)最后一个节点没有下一个节点,地址域赋值为NULL。

链表是一个数据+指针的结构体集合,指针指向链表中下一数据结构体,按链表的结构,可分为单向链表,双向链表,循环链表,结构分别如下图所示:链表

链表特征

1、(单)链表:必须有链表头pHeader;
2、通过链表头,可以顺次向下访问所有节点。
3、如果是空链表链表头为0,pHeader=NULL;
4、链表尾节点:类似于null结尾的字符串,最后一个节点的指针pNext==0;
5、可以在任意位置插入和删除节点。

链表的操作

链表的操作包括:插入,删除,反转,修改和查找。

链表的声明

#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include "iostream"
#include "vector"
using namespace std;
typedef int DATA;
struct node{
    DATA data;
    node* P_next=0;
    node(DATA _data){
        data = _data;
    }
};

class linkedlist{
    int length=0;
public:
    node *header, *tail;
    void pushback(DATA _data);  //尾插入数据
    void insert_node(DATA _data, int position); //在某个位置插入数据
    void delete_node(DATA _data); //删除数据
    vector<node*> search_node(DATA _data); //查找数据
    void modify_node(DATA _data1, DATA _data2); //修改数据
    void roll_back();  //链表反转
    void printlist(); //打印链表
    linkedlist(){

    };
    ~linkedlist(){
        if (length>0){
            node* temp_node;
            while (header->P_next) {
                temp_node = header->P_next;
                delete header;
                header = temp_node;
            }
            delete header;
        }
        cout<<"Deconstructed successfully!"<<endl;
    }

};

注意:链表一般是建立在堆上的,所以一定要对链表进行析构,以回收新开辟的堆空间。

链表的插入

链表的插入
过程包括以下三步:
step1:找到要插入的位置以及该位置原来的元素以及指向该位置的指针;
step2:生成新的元素;
step3:将step1中的指针指向新的元素,该元素的指针对象指向step1中元素

void linkedlist::insert_node(DATA _data, int position){
    if(position <= length){
        int index = 0;
        node* temp_node = header , *last_node = 0;
        while (index<position) {
            index ++;
            temp_node = temp_node->P_next;
            if(index == position -1)
            {
                last_node = temp_node;
                if(temp_node->P_next) temp_node = temp_node->P_next;
                else temp_node = 0;
                break;
            }
        }
        node* newnode = new node(_data);

        if(temp_node){
            newnode->P_next = temp_node;
        }
        else{
            newnode->P_next = 0;
            tail = newnode;
        }

        if(last_node)   last_node->P_next = newnode;
        else{
        header = newnode;
        }
        length++;

    }
    else cout<<"position 超出索引"<<endl;
}

链表的尾插入

与链表的插入很相似,只是将新生成的结构数据指针设为0

void linkedlist::pushback(DATA _data){
    if(length == 0){
        header = new node(_data);
        tail = header;
    }
    else{
        node* newnode = new node(_data);
        tail->P_next = newnode;
        tail = newnode;
    }
    length ++;
}

链表的查找

采用从头到尾遍历的方法(感觉这种查找方法挺低效率的)。

vector<node*> linkedlist::search_node(DATA _data){
  vector<node*> nodes;
  if (length>0){
      node* temp_node = header;
      while(temp_node->P_next){
        if(temp_node->data == _data){
            nodes.push_back(temp_node);
        }
        else temp_node = temp_node->P_next;
      }
      if(temp_node->data == _data) nodes.push_back(temp_node);
  }
  return nodes;
}

链表的元素删除

链表的删除
链表的删除主要包括以下步骤:
step1:找到要删除的元素及位置以及指向该位置的指针;
step2: 将step1中的指针指向该元素下一个元素;
step3: 删除该元素。

void linkedlist::delete_node(DATA _data){
    if(length >0){
        node* temp_node = header, *last_node=header;
        while (temp_node->P_next){
            if(temp_node->data == _data){
                last_node->P_next = temp_node->P_next;
                delete temp_node;
                temp_node = last_node;
                length --;
            }
            last_node = temp_node;
            temp_node = temp_node->P_next;
        }

        if(temp_node->data == _data) {
            delete temp_node;
            last_node->P_next = 0;
            length --;
            tail = last_node;
        }
    }
}

链表的反转

链表的反转,就是将链表原来的指向关系进行互逆,及原来元素A中的指针指向B,反转后变成B中的指针指向A,头尾交换。

void linkedlist::roll_back(){
    if(length >1){
        node* next_node, *last_node = header, *this_node=header->P_next;
        last_node->P_next = nullptr;
        tail = last_node;
        while(this_node->P_next){
            next_node = this_node->P_next;
            this_node->P_next = last_node;
            last_node = this_node;
            this_node = next_node;
        }
        header=this_node;
        header->P_next = last_node;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值