• 单链表


    单链表思路:
    1、表示结点,一个数据域,一个链接域,可以采用结构体或者类表示,这里
    使用结构体表示。为简单起见,数据类型设置为int。
    2、用类表示单链表这个抽象数据类型,包含数据和操作。
    1)由于需要一个起始的链表头来开始建立链表,则需声明一个保护类型的指针。
    2)建立一个类之后首先需要设定类的构造函数和析构函数。
    3)然后是建立单链表,输出单链表。
    4)插入、删除结点。
    5)辅助函数:判断是否为空链表的函数;定位到给定的索引处。

    单链表的结点用结构体来表示:

    1
    2
    3
    4
    5
    struct  LinkNode
    {
        int data;   //数据域
        LinkNode *link; //结点本身的链接域
    };

    单链表的抽象数据类型用类表示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    class LinkList
    {
    private:
        LinkNode *head; //链表头指针,位置不可以改变,建立该链表的时候确定
    public:
        LinkList(){}    //构造函数
        ~LinkList();    //析构函数
     
        /*----------------建立、输出单链表--------------*/
        void InitLinkList();        //建立单链表
        void OutputLinkList();      //输出单链表
         
     
        /*----------------插入、删除结点-------------*/
        bool InsertNode(int data,int index);    //插入结点
        bool DeleteNode(int index); //删除结点
    };

     下面介绍单链表的几种关键算法,单链表的建立,输出,插入结点和删除结点:

    建立单链表的算法:
    1、输入一个值,然后将该值赋值给当前结点的数据域。
    2、拉链:head不能改变,所以需要另外声明一个指针*last。
    1)将该值赋值给这个新建结点指针的数据域。
    2)采用后插法建立单链表
    3、将链表指针的最后一个链接域赋值为NULL,容易忽略 head->link=NULL
    编程经验:
    1、在分配一个存储空间后,加上测试语句是好的编程实践

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    void LinkList::InitLinkList()
    {
        int data;   //输入的结点值,以999号结束
        cout<<"请输入单链表的结点值:"<<endl;
        cin>>data;
        LinkNode *last;     //head指针不可以改变位置
        head=new LinkNode;  //链表头指针,要在这里进行初始化,重要,链表的头指针不能改变
        if(head==NULL){cerr<<"分配错误!"<<endl;}
        last=head;
        while(data!=999)    //如果该值不为999,则拉链,不断重复该过程
        {
            LinkNode* NewNode=new LinkNode;     //新建一个结点,用于拉链
            if(NewNode==NULL){cerr<<"分配错误!"<<endl;}
             
            NewNode->data=data;    //附加头结点
            //NewNode=head->link;
            //head=NewNode;       //这两句是典型的错误
     
            last->link=NewNode;
            last=NewNode;         //这样也不行
            cin>>data;              //输入改值
        }
     
        last->link=NULL;
     
    }

     输出单链表算法:
    1、根据链表头指针,输出该链表指针所指向的数据域。
    2、判断该指针是否为空,不为空,则向下推进一个。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void LinkList::OutputLinkList()
    {
        LinkNode *current=head->link;    //带附加头结点的链表
        if(current==NULL){cerr<<"分配错误!"<<endl;}
        cout<<"单链表为:"<<endl;
        while(current!=NULL)
        {
            cout<<current->data<<" ";
            current=current->link;   //向下推进一个位置
        }
        cout<<endl;
         
    }

     插入结点算法:
    1、在index位置插入元素,需要先找到第index个元素的位置。
    2、插入该元素到index位置,可能出现的情况:
    1)先定义一个插入的结点指针*current。
    2)声明一个num,用来记录当前的位置和所给的index进行比较。
    3)判断num是否等于所给的index值,如果等于,就进行结点的插入操作。
    a)需要注意的是current要在index-1的位置。
    b)如果不相等,则current位置推进一个位置。
    c)最后判断如果num<index 则表明链表太短,这样的操作属于非法操作。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    bool LinkList::InsertNode(int data,int index)
    {
        int num=0;      //用来记录当前的位置
        LinkNode *current=head; //辅助结点,必须进行初始化
        LinkNode *newNode=new LinkNode; //待插入结点
        newNode->data=data;  //将该值赋值给该结点值
     
        while(current!=NULL)
        {
            num++;  //由于带附加头结点,所以num先要加1,表示第一个结点
            if(index==num)     
            {
                newNode->link=current->link;
                current->link=newNode;           //这两句进行结点的插入操作
            }
            else
            {
                current=current->link;   //推进一个位置
            }
        }
     
        if(num<index)
        {
            cout<<"单链表长度太短"<<endl;
            return false;
        }
        else
        {
            return true;
        }
    }
     
    /*-----------------------------------------*/

     单链表删除算法:
    1、删除给的索引处的结点。
    2、需要定义个current指针和一个计数器num;
    3、如果num等于给定的index,则需要声明另外一个表示要删除的结点的指针。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    bool LinkList::DeleteNode(int index)
    {
        LinkNode *current=head; //循环指针
        int num=0;
     
        while(current!=NULL)
        {
            num++;      //由于带附加头结点,所以需要先将num加1
     
            if(index==num)
            {
                LinkNode *p=current->link;   //待删除的结点
                current->link=p->link;
                delete p;
            }
            else
            {
                current=current->link;
            }
        }
        if(index>num)
        {
            cout<<"单链表的长度太短"<<endl;
            return false;
        }
        else
        {
            return true;
        }
    }
  • 相关阅读:
    python并发之concurrent.futures
    全局解释器锁--GIL
    ASP 注释
    ASPxGridView 下拉框不让输入
    leftjoin及多个leftjoin执行顺序
    视图view没有主键,但可以添加唯一索引
    ASPxGridView KeyFieldName
    联合主键
    AspxGridView使用教程
    ASP Session 对象
  • 原文地址:https://www.cnblogs.com/fistao/p/3097720.html
Copyright © 2020-2023  润新知