• 数据结构之单链表


    单链表相对于顺序表来说拥有可以减少使用空间,可以更快速的对表中数据进行插入与删除的优点,而对于顺序表,查找一个元素的时间复杂度仅仅为O(1),然而单链表却需要遍历寻找。

    以下是我写的单链表,功能不知完全不完全,希望大家都有一些收获吧。

    /************************************************************************/
    /*             以下是关于线性表链接存储(单链表)操作的14种算法        */
     
    /* 1.初始化线性表,即置单链表的表头指针为空 */
    /* 2.创建线性表,此函数输入零终止读取数据*/
    /* 3.打印链表,链表的遍历*/
    /* 4.销毁线性表L中的所有元素,即释放单链表L中所有的结点,使之成为一个空表 */
    /* 5.返回单链表的长度 */
    /* 6.检查单链表是否为空,若为空则返回1,否则返回0 */
    /* 7.查找第i个元素,若为查找到输出提示语句,否则返回查找值*/
    /*  8.查找第i个元素的前驱。*/
    /*  9.查找第i个元素的后继。*/
    /*  10.确定一个数的位置,若找到输出位置所在,找不到,返回提示语句。*/
    /* 11.在链表中插入一个元素*/
    /* 12.在链表中删除一个元素*/
    /* 13.合并两个有序的链表.*/
    /* 14.给定一个数,看是否可以在链表中删除。*/
    FISRT:    
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    using namespace std;
    #define TRUE 1
    #define FALSE 0
    #define OK 1
    #define ERROR 0
    #define OVERFLOW -2
    typedef int elemType;

    这里是一些规定,以及需要用到的头文件。

    接下来就要来看单链表的储存结构:

    typedef struct Node
    {
        elemType e;
        struct Node *next;
    };
    /* 1.初始化线性表,即置单链表的表头指针为空 */
    void InitList(Node **head)
    {
        *head=NULL;
        cout<<"get a empty list"<<endl;
    }

    /* 2.创建线性表,此函数输入零终止读取数据*/

    void createList(struct Node **head)
    {
        struct Node *t,*w;
        int shu;
        *head = NULL;
        cout<<"请输入一个数:(输入零终止输入) :";
        cin>>shu;
        while(shu!=0)
        {
            t=(Node *)malloc(sizeof(struct Node));
            t->e=shu;
            t->next=NULL;
            //由于没有头结点,需要判断链表首结点是否为空,若为空,就插入到首节点,不为空则插入已有节点之后。
            if(*head==NULL)
            {
                *head=t;
            }
            else
            {
                w->next=t;
            }
            w=t;
            cout<<"请输入一个数:(输入零终止输入) :";
            cin>>shu;
        }
    }

    /* 3.打印链表,链表的遍历*/

    void visit(struct Node *head)
    {
        if(head==NULL) cout<<"not exit"<<endl;//链表为空
        else//链表不为空
        {
            while(head)
            {
                if(head->next!=NULL)
                    cout<<head->e<<" ";
                else
                    cout<<head->e<<endl;//最后一个后面没有空格,比较严谨 
                head=head->next;
            }
        }
    }

    /* 4.销毁线性表L中的所有元素,即释放单链表L中所有的结点,使之成为一个空表 */

    void Destroy(struct Node *head)
    {
        Node *p;
        while(head!=NULL)
        {
            p=head;
            head=head->next;
            free(p);
        }
        cout<<"finish"<<endl;
    
    }

    /* 5.返回单链表的长度 */

    int listlength(Node *head)//遍历的方法求长度,也可以边创建链表,边计算长度。
    {
        int len=0;
        while(head!=NULL)
        {
            head=head->next;
            len++;
        }
        return len;
    }

    /* 6.检查单链表是否为空,若为空则返回1,否则返回0 */

    elemType isEmptyList(Node *head)
    {
        if(head == NULL)
        {
            cout<<"isEmptyList函数执行,链表为空
    ";
            return 1;
        }
        cout<<"isEmptyList函数执行,链表非空
    ";
        return 0;
    }

    /* 7.查找第i个元素,若为查找到输出提示语句,否则返回查找值*/

    elemType getelem(Node *head,int pos)
    {
        int i=0;
        if(pos<1) cout<<"please check input"<<endl;
        if(head==NULL)//表为空
        {
            cout<<"not exit"<<endl;
            exit(ERROR);
        }
        while(head!=NULL)
        {
            ++i;
            if(i==pos)
            {
                break;
            }
            else
            {
                head=head->next;
            }
    
        }
        if(i<pos)
        {
            cout<<"pos is larger than i,please check intput"<<endl;
        }
        return head->e;
    }

    /*  8.查找第i个元素的前驱。*/

    elemType priorelem(Node *head,int pos)
    {
        int i=0;
        if(pos<1) cout<<"please check input"<<endl;
        if(head==NULL)
        {
            cout<<"not exit"<<endl;
            exit(ERROR);
        }
        while(head!=NULL)
        {
            ++i;
            if(i==pos-1)
            {
                break;
            }
            else
            {
                head=head->next;
            }
    
        }
        if(i<pos-1)
        {
            cout<<"pos is larger than i,please check intput"<<endl;
        }
        return head->e;
    }

    /*  9.查找第i个元素的后继。*/

    elemType nextelem(Node *head,int pos)
    {
        int i=0;
        if(pos<1) cout<<"please check input"<<endl;
        if(head==NULL)
        {
            cout<<"not exit"<<endl;
            exit(ERROR);
        }
        while(head!=NULL)
        {
            ++i;
            if(i==pos+1)
            {
                break;
            }
            else
            {
                head=head->next;
            }
    
        }
        if(i<pos+1)
        {
            cout<<"pos is larger than i,please check intput"<<endl;
        }
        return head->e;
    }

    /*  10.确定一个数的位置,若找到输出位置所在,找不到,返回提示语句。*/

    void locateelem(Node *head,int pos)
    {
        if(head==NULL) cout<<"not exit"<<endl;
        else
        {
            int i=0,flag=0;
            while(head!=NULL)
            {
                ++i;
                if(pos==head->e)
                {
                    flag=1;
                    break;
                }
                head=head->next;
            }
            if(flag==1)cout<<"元素"<<pos<<"的位置为:"<<i<<endl;
            else cout<<"该链表中无此元素"<<endl;
        }
    }

    /* 11.在链表中插入一个元素*/

    void listinsert(Node **head,int w,int n)
    {
        struct Node *add;
        struct Node *jihead;
        int count=1;//计数器
        jihead = *head;
        add = (Node* )malloc(sizeof(Node));
        add->e = n;
        add->next = NULL;
        if(*head == NULL)//如果表中无数据就插入在表头
        {
            *head=add;
        }
        if(w == 1)//在第一个位置插入数据
        {
            add->next = *head;
            *head = add;
            return ;
        }
        while(jihead!=NULL)
        {
            count++;
            if(count==w)
            {
                add->next=jihead->next;
                jihead->next=add;
                return ;
            }
            jihead=jihead->next;
        }
        jihead->next=add;//最后也没找到位置,就插在末尾。
    }

    /* 12.在链表中删除一个元素*/

    void listdelete(Node **head,int n)
    {
        struct Node *dele,*jihead;
        jihead=*head;
        int count=1;//依旧还是计数器
        if(*head==NULL)
        {
            cout<<"链表为空"<<endl;
        }
        if(n==1)//删除第一位
        {
            dele=*head;
            *head=(*head)->next;
            free(dele);
        }
        while(jihead!=NULL)
        {
            count++;
            if(count==n)
            {
                dele=jihead->next;
                jihead->next=jihead->next->next;
                free(dele);
            }
            jihead=jihead->next;
        }
    }

    /* 13.合并两个有序的链表.*/

    struct Node* SortedMerge(struct Node* a, struct Node* b)//两个单调不递减的有序序列
    {
        struct Node* result = NULL;
        if(a == NULL)  return b;
        else if(b == NULL)  return a;
        /*Pick either a or b, and recur */
        if(a->e <= b->e)
        {
            result = a;
            result->next = SortedMerge(a->next, b);//递归
        }
        else
        {
            result = b;
            result->next = SortedMerge(a, b->next);
        }
        return (result);
    }

    /* 14.给定一个数,看是否可以在链表中删除。*/

    void listdrop(Node **head,int pos)
    {
        struct Node *del,*jihead;
        jihead=*head;
        if((*head)->e==pos)
        {
            del=*head;
            *head=(*head)->next;
            free(head);
        }
        else
        {
            while(jihead!=NULL)
            {
                if(jihead->next->e==pos)
                {
                     del=jihead->next;
                     jihead->next=jihead->next->next;
                     free(del);
                     return;
                }
                jihead=jihead->next;
            }
        }
    }

    主函数:

    int main()
    {
    
        struct Node *p1;
        struct Node *p2;
        struct Node *p3;
        createList(&p1);
        visit(p1);
        int n;
        cin>>n;
        listdrop(&p1,n);
        visit(p1);
        createList(&p2);
        visit(p2);
        p3=SortedMerge(p1,p2);
        //cout<<"length: "<<listlength(p)<<endl;
        //visit(p3);
        //cout<<"---------------"<<endl;
    
        //cout<<"查找第i位元素: "<<getelem(p,2)<<endl;
        //cout<<"查找第i位元素前驱: "<<priorelem(p,2)<<endl;
        //cout<<"查找第i位元素后继: "<<nextelem(p,2)<<endl;
        //locateelem(p,2);
        //listinsert(&p,3,99);
        //visit(p);
        //listdelete(&p,4);
        //visit(p);
        //InitList(&p);
        //Destroy(p);
        //visit(p);
        return 0;
    }

    新手博文,如有缺憾,还望指教。

  • 相关阅读:
    模拟算法(八)
    迭代算法(七)
    试探法是一种委婉的做法(六)
    贪心算法并不贪婪(五)
    各个击破的分治算法(四)
    充分利用自己的递归算法(三)
    一起学Spring之Web基础篇
    C# 利用AForge进行摄像头信息采集
    一起学Spring之注解和Schema方式实现AOP
    一起学Spring之AOP
  • 原文地址:https://www.cnblogs.com/famousli/p/4227928.html
Copyright © 2020-2023  润新知