• 实现带有头结点的链表


    首次写博客,请大神不要吐槽微笑

           要实现带头结点的链表,重要的是先搞清楚头结点是什么。链表里有几个名词,头指针,头结点,首结点,概念要明白,会区别,弄懂了这一步,链表的开始就没问题了。头指针即是头结点的地址,头结点数据域为空(当然你也可以用头结点的数据域来保存链表结点的个数),指针域的指针指向首结点,首结点即是你要储存数据的第一个结点。



    /*
    建立带有头结点的链表
    包含函数creat,insert,getelemt,del,print
    */
    #include<string>
    #include<cstdio>
    #include<iostream>
    #define null 0
    #define ok 1
    #define error 0
    using namespace std;
    typedef struct Node
    {
        string s;
        struct Node *next;
    } node,*linklist;
    int n=0;
    void creat(linklist &Head)
    {
        linklist p,q;
        Head=p=q=new node();//新链表建立时先建立头结点(即为头结点开辟空间)
        string ss;//用来存输入的数据
        if(Head==null)printf("内存开辟失败
    ");
        while(cin>>ss)
        {
            p=new node();//建立一个新的结点
            p->s=ss;//将新的结点的值赋为ss
            n++;//个数加一
            q->next=p;//前个结点的指针指向新结点
            q=p;//更新结点
        }
        q->next=null;//将尾结点的next赋为null
    }
    int  getElem(linklist &Head,int i,string &e)
    {
        linklist p,q;
        p=Head->next;//先使指针指向首结点(即第一个保存信息的结点,注意不是头结点)
        int j=1;
        while(p!=null&&j<i)//寻找i结点
        {
            p=p->next;
            j++;
        }
        //此时p指向i结点,且j=i;
        if(p==null||j>i)
        {
            cout<<"run error"<<endl;
            return error;
        }
        e=p->s;//将得到的i结点的数据赋给e
    
        return ok;
    }
    int ListInsert(linklist &Head,int i,string &e)//在原链表的i-1结点与i结点之间插入新的结点
    {
        linklist p,q;
        if(i==1)//如果在第一个元素之前加入新结点
        {
            q=new node();//建立一个新的结点
            q->s=e;//新结点的数据赋为e
            q->next=Head->next; //新结点的next指向原表首结点
            Head->next=q; //头结点的next指向新结点
            n++;//个数加一
            return ok;//直接退出
        }
        p=Head->next;//先使指针指向首结点(即第一个保存信息的结点,注意不是头结点)
        int j=1;
        while(p!=null&&j<i-1)//寻找i-1结点
        {
            p=p->next;
            j++;
        }//此时p指向i-1结点,且j=i-1;
        if(p==null||j>i-1)
        {
            cout<<"run error"<<endl;
            return error;
        }
        q=new node();//建立一个新的结点
        q->s=e;//新结点的数据赋为e
        q->next=p->next;//新节点的next指向原本的i结点(因为现在不是要在原链表的i-1结点与i结点之间插入新的结点吗?使新结点成为新链表的i结点)
        p->next=q;//i-1结点的next指向新结点
        n++;//个数加一
        return ok;
    }
    int ListDel(linklist &Head,int i)//删除链表的第i个元素
    {
        linklist p,q;
        if(i==1)//如果删除首结点
        {
            Head->next=Head->next->next;//画个图就理解了
            n--;//个数减一
            return ok;//直接退出
        }
        p=Head->next;//先使指针指向首结点(即第一个保存信息的结点,注意不是头结点)
        int j=1;
        while(p!=null&&j<i-1)
        {
            p=p->next;
            j++;
        }  //此时p指向i-1结点,且j=i-1;
        if(p==null||j>i)
        {
            cout<<"run error"<<endl;
            return error;
        }
        cout<<j<<endl;
        q=p->next;//将i结点的地址给q
        p->next=q->next;//i-1结点的next指向i+1结点(现在q的next指向i+1结点)
        n--;//个数减一
        return ok;
    }
    void Print(linklist Head)//打印链表
    {
        linklist p;
        p=Head->next;//先使指针指向首结点(即第一个保存信息的结点,注意不是头结点)
        while(p)
        {
            cout<<p->s<<endl;
            p=p->next;
    
        }
        cout<<n<<endl;//打印个数
        cout<<endl;
    }
    int main()
    {
        linklist Head;
        creat(Head);
        Print(Head);
    
        string tmp;
        getElem(Head,3,tmp);
        cout<<tmp<<endl;//打印得到的数据
    
        tmp="ILOVEYOU";
        ListInsert(Head,5,tmp);
        ListDel(Head,1);
        Print(Head);
    }
    /*
    I
    will
    love
    you
    forever
    Users
    Administrator
    Documents
    linklist
    Head
    creat
    Head
    string
    tmp
    get
    Eltmp
    */
    

  • 相关阅读:
    5分钟带你了解Kafka的技术架构
    聊聊我的知识体系
    你分得清楚Maven的聚合和继承吗?
    为抖音而生的多闪,如何获取抖音的用户数据?
    消息中间件系列第3讲:使用消息队列需要考虑的几个问题
    消息中间件系列第2讲:如何进行消息队列选型?
    消息中间件系列第1讲:为什么要用消息队列?
    JVM规范系列开篇:为什么要读JVM规范?
    安全编码实践之三:身份验证和会话管理防御
    安全编码实践之二:跨站脚本攻击防御
  • 原文地址:https://www.cnblogs.com/hjch0708/p/7554852.html
Copyright © 2020-2023  润新知