IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> c++数据结构---单链表 -> 正文阅读

[数据结构与算法]c++数据结构---单链表

单链表的概念

这里每个节点存储:自己的数据元素和指向其后继结点的指针?
正是这种设计反映了结点之间的关系

这里的头结点的设计只是为了插入和删除操作的方便,比如在第一个元素前插入结点,如果没有头指针,那么从实现来说很困难。

而且链表最后一个元素如果没有后继,其后继结点的指针置为空

单链表类的设计

  • 首先需要一个结点类----里面存储自己的元素数据和后继结点的指针
  • 对于链表类而言----只需存储用于遍历结点的头指针以及为了计算链表长度方便而设计的curLength
private:
    struct node{
        elemType data;
        node* next;
    };
    node* head;
    int curLength;

几个设计:

  • node设计成结构而非类,是因为链表函数需要频繁访问其存储的数据,struct的成员默认共有,而class成员默认私有
  • 由于struct成员和类一样也需要初始化,从而要补充构造函数和析构函数
  • 由于插入和删除操作要找第i个结点的位置,为了方便起见,设计一个私有成员函数move(i)?
private:
    struct node{
        elemType data;
        node* next;
        //构造函数
        node(const elemType& x,node* n=NULL){
            data=x;
            next=n;
        }
        node():next(NULL){}
        //析构函数
        ~node(){};
    };
    node* head;
    int curLength;
    //返回指向第i个结点的指针
    node* move(int i)const;

?链表类的构造和析构函数

 sLinklist(){
        head=new node;//创建新节点,调用了无参构造node():next(NULL){}
        curLength=0;
    }
    ~sLinklist(){
        clear();//clear操作会delete所有结点数据
        delete head;//
    }

?clear()

//clear()
template<class elemType>
void sLinklist<elemType>::clear(){
    node* p=head->next;//要销毁结点
    node* q;//辅助结点,记录下一个销毁位置
    head->next=NULL;//clear结果
    while(p!=NULL){
        q=p->next;
        delete p;
        p=q;
    }
    curLength=0;
}

两步:

clear结果-----head->next=NULL;? ? curLength=0;

delete链表已有数据结点:

双指针,p要销毁的节点,必须是head->next,q记录销毁的下一个位置

insert(i,x)

首先实现move(i)

template<class elemType>
sLinklist<elemType>::node* sLinklist<elemType>::move(int i)const{
    node* p=head;
    while(i-->=0) p=p->next;
    return p;
}

?注意move是私有成员函数,其类型前也要加上---sLinklist<elemType<::

?要找到第i个位置的元素,头指针要向后移动i次.注意和数组一样从0开始

?注意:vs的gcc在编译时候需要在sLinklist前加上“typename”

remove(i)

//remove(i)
template<class elemType>
void sLinklist<elemType>::remove(int i){
    node* p=move(i-1);
    node* q=p->next;
    p->next=q->next;
    delete q;
    --curLength;
}

?visit(i);search(x);traverse()

//search(x)
template<class elemType>
int sLinklist<elemType>::search(const elemType& x) const{
    node* p=head->next;
    int i=0;
    while(p&&p->data!=x){
        p=p->next;
        i++;
    }
    if(p==NULL){
        return -1;
    }
    else
        return i;
}
//visit(i)
template<class elemType>
 elemType sLinklist<elemType>::visit(int i) const{
       node* p=move(i);
       return p->data;
 }
//traverse()
#include<iostream>
using namespace std;
template<class elemType>
void sLinklist<elemType>::traverse() const{
    node *p=head->next;
      while(p){
         cout<<p->data<<",";
         p=p->next;
      }
      cout<<endl;
}

总程序:

list.h

#ifndef MY_list
#define MY_list
template<class elemType>
class list{
    public:
    virtual ~list(){};
    virtual void clear()=0;
    virtual int listLength() const=0;
    virtual void insert(int i,const elemType& x)=0;
    virtual void remove(int i)=0;
    virtual int search(const elemType& x) const=0;
    virtual elemType visit(int i) const=0;
    virtual void traverse() const=0;
};
#include"sLinklist.h"
#endif

sLinklist.h

#ifndef MY_slinklist
#define MY_slinklist
#include"list.h"
template<class elemType>
class sLinklist:public list<elemType>{
private:
    struct node{//和类一样加;
        elemType data;
        node* next;
        //构造函数
        node(const elemType& x,node* n=NULL){
            data=x;
            next=n;
        }
        node():next(NULL){}
        //析构函数
        ~node(){};
    };
    node* head;
    int curLength;
    //返回指向第i个结点的指针
    node* move(int i) const;
public:
    sLinklist(){
        head=new node;//创建新节点,调用了无参构造node():next(NULL){}
        curLength=0;
    }
    ~sLinklist(){
        clear();//clear操作会delete所有结点数据
        delete head;//
    }
    void clear();
    int listLength() const{
        return curLength;
    }
    void insert(int i,const elemType& x);
    void remove(int i);
    int search(const elemType& x) const;
    elemType visit(int i) const;
    void traverse() const;
};
//clear()
template<class elemType>
void sLinklist<elemType>::clear(){
    node* p=head->next;//要销毁结点
    node* q;//辅助结点,记录下一个销毁位置
    head->next=NULL;//clear结果
    while(p!=NULL){
        q=p->next;
        delete p;
        p=q;
    }
    curLength=0;
}
//move(i)
template<class elemType>
typename sLinklist<elemType>::node * sLinklist<elemType>::move(int i) const {
    node* p=head;
    while(i-->=0) p=p->next;
    return p;
}
//insert(i,x)
template<class elemType>
void sLinklist<elemType>::insert(int i,const elemType& x){
      node* pos=move(i-1);
      pos->next=new node(x,pos->next);//申请结点并把它next链入链表
      ++curLength;
 }
//remove(i)
template<class elemType>
void sLinklist<elemType>::remove(int i){
    node* p=move(i-1);
    node* q=p->next;
    p->next=q->next;
    delete q;
    --curLength;
}
//search(x)
template<class elemType>
int sLinklist<elemType>::search(const elemType& x) const{
    node* p=head->next;
    int i=0;
    while(p&&p->data!=x){
        p=p->next;
        i++;
    }
    if(p==NULL){
        return -1;
    }
    else
        return i;
}
//visit(i)
template<class elemType>
 elemType sLinklist<elemType>::visit(int i) const{
       node* p=move(i);
       return p->data;
 }
//traverse()
#include<iostream>
using namespace std;
template<class elemType>
void sLinklist<elemType>::traverse() const{
    node *p=head->next;
      while(p){
         cout<<p->data<<",";
         p=p->next;
      }
      cout<<endl;
}
#endif

maintest.cpp

#include<iostream>
#include"list.h"
using namespace std;
int main(){
    sLinklist<int> slink;
    slink.insert(0,7);
    slink.insert(1,17);
    slink.insert(2,8);
    slink.insert(3,19);
    slink.insert(4,9);
    slink.traverse();
    slink.remove(2);
    slink.traverse();
    cout<<slink.listLength()<<endl;
    cout<<slink.search(17)<<endl;
    cout<<slink.visit(2);
    return 0;
}

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-05-05 11:44:27  更:2022-05-05 11:45:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 5:56:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码