zoukankan      html  css  js  c++  java
  • 线性表及其操作

    线性链表的概念:

    以链式结构存储的线性表称之为线性链表。

    特点是该线性表中的数据元素可以用任意的存储单元来存储。线性表中逻辑相邻的两元素的存储空间可以是不连续的。为表示逻辑上的顺序关系,对表的每个数据元素除存储本身的信息之外,还需存储一个指示其直接衙继的信息。这两部分信息组成数据元素的存储映象,称为结点。

    2000:1000
    2000:1010
    2000:1020
    2000:1030
    2000:1040
    2000:1050
    2000:1060
    ...
    2000:4000
    头指针2000:1006 2000:1030
    a3 2000:1040
    a6 NULL
    a1 2000:1060
    a4 2000:1050
    a5 2000:1020
    a2 2000:1010
    数据域 指针域
       
     
     
     
    <-数据域+指针域
     
     
     
     
     

    例:下图是若干抽屉,每个抽屉中放一个数据元素和一个指向后继元素的指针,一号抽屉中放线性表的第一个元素,它的下一个即第二个元素的位置标为5,即放在第5个抽屉中,而第三个放在2号抽屉中。第三个元素即为最后一个,它的下一个元素的指针标为空,用0表示。

    用线性链表表示线性表时,数据元素之间的逻辑关系是由结点中的指针指示的

    二、线性链表的存储实现

    struct LNODE{

    ElemType data;

    struct LNODE *next;

    };

    typedef struct LNODE LNode;

    typedef struct LNODE * LinkList;

    头指针与头结点的区别:

    头指针只相当于结点的指针域,头结点即整个线性链表的第一个结点,它的数据域可以放数据元素,也可以放线性表的长度等附加信息,也可以不存储任何信息。

    三、线性表的操作实现(类C语言)

    1初始化操作

    Status Init_L(LinkList L){

    if (L=(LinkList *)malloc(sizeof(LNode)))

    {L->next=NULL;return 1;}

    else return 0;

    }

    2插入操作

    Status ListInsert_L(LinkList &L,int i,ElemType e){

    p=L,j=0;

    while(p&&j<i-1){p=p->next;++j;}

    if(!p||j>i-1) return ERROR;

    s=(LinkList)malloc(sizeof(LNode));

    s->data=e;s->next=p->next;

    p->next=s;

    return OK;

    }//ListInsert_L

    3删除操作

    Status ListDelete_L(LinkList &L,int i,ElemType &e){

    p=L,j=0;

    while(p&&j<i-1){p=p->next;++j;}

    if(!p->next||j>i-1) return ERROR;

    q=p->next;p->next=q->next;

    e=q->data;free(q);

    return OK;

    }//ListDelete_L

    4取某序号元素的操作

    Status GetElem_L(LinkList &L,int i,ElemType &e){

    p=L->next,j=1;

    while(p&&j<i){p=p->next;++j;}

    if(!p||j>i) return ERROR;

    e=p->data;

    return OK;

    }//GetElem_L

    5归并两个单链表的算法

    void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc){

    //已知单链线性表La和Lb的元素按值非递减排列

    //归并后得到新的单链线性表Lc,元素也按值非递减排列

    pa=La->next;pb=Lb->next;

    Lc=pc=La;

    while(pa&&pb){

    if(pa->data<=pb->data){

    pc->next=pa;pc=pa;pa=pa->next;

    }else{pc->next=pb;pc=pb;pb=pb->next;}

    }

    pc->next=pa?pa:pb;

    free(Lb);

    }//MergeList_L

    C语言实现的例子

    四、总结

    1、线性链表的概念。

    2、线性链表的存储

    3、线性链表的操作

    下面是具体的事例。

    一、    线性表及其操作
    1、    尾插法建立一个单链表,并按顺序输出
    2、    单链表的元素查找,按内容查找
    3、    元素插入操作
    4、    按内容元素删除操作
    5、    按位置删除元素
    6、    建立双向链表
    7、    单链表就地逆置
    8、    约瑟夫环问题
    一、线性表及其操作

    //All copyright are preserved by cobby
    /*尾插法建立一个单链表,并按顺序输出*/

    #define NULL 0            /*宏定义*/
    typedef struct node        /*定义结点类型的数据结构*/
    {
        char c;            /*数据域,类型为字符型*/
        struct node *next;    /*指针域,类型为本结构体类型*/
    }*L;            /*类型重定义,即Node和*L和struct node等价*/

    main()
    {
        L l,p,q;        /*用指针类型定义三个结点类型的指针*/
        char ch;
        l=(L)malloc(sizeof(L));    /*分配内存空间*/
        l->c='\0';            /*为头结点的数据域赋值,值为空*/
        l->next=NULL;            /*指明下一个结点目前不存在*/
        q=l;                /*q为游动指针,链表结点的连结要用*/
        printf("Input a character:\n");
        scanf("%c",&ch);
        getchar();        //此语句用来吸收键盘输入的回车符,没有其它含义
        while(ch!='!')            /*输入!表示输入结束*/
        {
            p=(L)malloc(sizeof(L));    /*为新输入的数据分配内存空间*/
            p->c=ch;
            p->next=NULL;            /*新输入的结点在链表的最后,即它的后面没有其它元素*/
            q->next=p;            /*q用于将上一个元素链接至当前新元素*/
            q=p;                /*q自己移到当前最后一个元素,以备继续链接所用*/
            scanf("%c",&ch);
            getchar();
        }
        q=l;                /*输入整个链表前,先将q移到链表头,l一般不动*/
        while(q->next!=NULL)        /*若q所指向的元素后面还有其它元素,则将该元素的数据输出*/
        {
            printf("%c-->",q->next->c);    /*q->next->c表示q所指向的下一个元素的数据*/
            q=q->next;            /*完成该元素的输出后,q移至下一个元素重复输出操作*/
        }
    }


    //All copyright are preserved bycobby
    /*单链表的元素查找,按内容查找*/


    #define NULL 0            /*宏定义*/
    typedef struct node        /*定义结点类型的数据结构*/
    {
        char c;            /*数据域,类型为字符型*/
        struct node *next;    /*指针域,类型为本结构体类型*/
    }*L;            /*类型重定义,即Node和*L和struct node等价*/

    main()
    {
        L l,p,q;        /*用指针类型定义三个结点类型的指针*/
        char ch;
        int n;
        l=(L)malloc(sizeof(L));    /*分配内存空间*/
        l->c='\0';            /*为头结点的数据域赋值,值为空*/
        l->next=NULL;            /*指明下一个结点目前不存在*/
        q=l;                /*q为游动指针,链表结点的连结要用*/
        printf("Input a character:\n");
        scanf("%c",&ch);
        getchar();
        while(ch!='!')            /*输入!表示输入结束*/
        {
            p=(L)malloc(sizeof(L));    /*为新输入的数据分配内存空间*/
            p->c=ch;
            p->next=NULL;            /*新输入的结点在链表的最后,即它的后面没有其它元素*/
            q->next=p;            /*q用于将上一个元素链接至当前新元素*/
            q=p;                /*q自己移到当前最后一个元素,以备继续链接所用*/
            scanf("%c",&ch);
            getchar();
        }
        q=l;                /*输入整个链表前,先将q移到链表头,l一般不动*/
        while(q->next!=NULL)        /*若q所指向的元素后面还有其它元素,则将该元素的数据输出*/
        {
            printf("%c-->",q->next->c);    /*q->next->c表示q所指向的下一个元素的数据*/
            q=q->next;            /*完成该元素的输出后,q移至下一个元素重复输出操作*/
        }

        /*--------以上为建立一个单链表-------------*/


        printf("\nInput a character you wanna find\n");
        scanf("%c",&ch);
        printf("\nthe character you wanna find is %c\n",ch);
        q=l->next;        /*q移至头结点的后一个元素,即实际第一个数据点*/
        n=1;    //位置计数器
        while(q!=NULL)        /*若q不为空,即该结点存在*/
        {
            if(q->c==ch)    /*字符匹配*/
                printf("character found in position %d\n",n);
            q=q->next;    /*移至下一个元素继续查找*/
            n++;
        }
    }


    //All copyright are preserved bycobby
    /*元素插入操作*/

    #define NULL 0            /*宏定义*/
    typedef struct node        /*定义结点类型的数据结构*/
    {
        char c;            /*数据域,类型为字符型*/
        struct node *next;    /*指针域,类型为本结构体类型*/
    }Node,*L;            /*类型重定义,即Node和*L和struct node等价*/

    main()
    {
        L l,p,q;        /*用指针类型定义三个结点类型的指针*/
        char ch;
        int pos,n;
        l=(L)malloc(sizeof(Node));    /*分配内存空间*/
        l->c='\0';            /*为头结点的数据域赋值,值为空*/
        l->next=NULL;            /*指明下一个结点目前不存在*/
        q=l;                /*q为游动指针,链表结点的连结要用*/
        printf("Input a character:\n");
        scanf("%c",&ch);
        getchar();
        while(ch!='!')            /*输入!表示输入结束*/
        {
            p=(L)malloc(sizeof(Node));    /*为新输入的数据分配内存空间*/
            p->c=ch;
            p->next=NULL;            /*新输入的结点在链表的最后,即它的后面没有其它元素*/
            q->next=p;            /*q用于将上一个元素链接至当前新元素*/
            q=p;                /*q自己移到当前最后一个元素,以备继续链接所用*/
            scanf("%c",&ch);
            getchar();
        }
        q=l;                /*输入整个链表前,先将q移到链表头,l一般不动*/
        while(q->next!=NULL)        /*若q所指向的元素后面还有其它元素,则将该元素的数据输出*/
        {
            printf("%c-->",q->next->c);    /*q->next->c表示q所指向的下一个元素的数据*/
            q=q->next;            /*完成该元素的输出后,q移至下一个元素重复输出操作*/
        }

        /*以上为建立一个单链表*/

        printf("Input the character and its position, such as s,3\n\n");
        scanf("%c,%d",&ch,&pos);
        q=l;
        n=1;
        while(n!=pos&&q->next!=NULL)        /*未找到插入位置,且后面还有元素*/
        {
            q=q->next;
            n++;
        }
        /*退出循环后,要么找到插入位置,要么表已到最后,输入的插入位置过大*/

        if(n<pos)    /*表已读完,仍未找到插入位置*/
            printf("\n\nincorrect position, insert failed\n\n");
        else        /*找到插入位置*/
        {
            /*将进行插入操作*/
            p=(L)malloc(sizeof(Node));    /*给新输入的数据分配内存空间*/
            p->c=ch;
            p->next=q->next;
            q->next=p;
        }

        /*操作完成,然后输出新表*/
        
        q=l;                /*输入整个链表前,先将q移到链表头,l一般不动*/
        while(q->next!=NULL)        /*若q所指向的元素后面还有其它元素,则将该元素的数据输出*/
        {
            printf("%c-->",q->next->c);    /*q->next->c表示q所指向的下一个元素的数据*/
            q=q->next;            /*完成该元素的输出后,q移至下一个元素重复输出操作*/
        }
    }


    //All copyright are preserved bycobby
    /*按内容元素删除操作*/

    #include<malloc.h>
    #include<stdio.h>

    #define NULL 0            /*宏定义*/
    typedef struct node        /*定义结点类型的数据结构*/
    {
        char c;            /*数据域,类型为字符型*/
        struct node *next;    /*指针域,类型为本结构体类型*/
    }Node,*L;            /*类型重定义,即Node和*L和struct node等价*/

    main()
    {
        L l,p,q;        /*用指针类型定义三个结点类型的指针*/
        char ch;
        int n;
        l=(L)malloc(sizeof(Node));    /*分配内存空间*/
        l->c='\0';            /*为头结点的数据域赋值,值为空*/
        l->next=NULL;            /*指明下一个结点目前不存在*/
        q=l;                /*q为游动指针,链表结点的连结要用*/
        printf("Input a character:\n");
        scanf("%c",&ch);
        getchar();
        while(ch!='!')            /*输入!表示输入结束*/
        {
            p=(L)malloc(sizeof(Node));    /*为新输入的数据分配内存空间*/
            p->c=ch;
            p->next=NULL;            /*新输入的结点在链表的最后,即它的后面没有其它元素*/
            q->next=p;            /*q用于将上一个元素链接至当前新元素*/
            q=p;                /*q自己移到当前最后一个元素,以备继续链接所用*/
            scanf("%c",&ch);
            getchar();
        }
        q=l;                /*输入整个链表前,先将q移到链表头,l一般不动*/
        while(q->next!=NULL)        /*若q所指向的元素后面还有其它元素,则将该元素的数据输出*/
        {
            printf("%c-->",q->next->c);    /*q->next->c表示q所指向的下一个元素的数据*/
            q=q->next;            /*完成该元素的输出后,q移至下一个元素重复输出操作*/
        }

        /*以上为建立单链表*/

        printf("input the character you wanna delete\n\n");
        scanf("%c",&ch);
        printf("the element you wanna delete is %c\n\n",ch);
        q=l->next;
        p=l;
        n=1;

        while(q!=NULL&&q->c!=ch)
        {
            p=q;
            q=q->next;
            n++;
        }
        /*退出循环时可能找到指定元素,也可能表读完,需要进一步判断*/
        
        if(q==NULL)
            printf("element not found, delete failed\n\n");
        else
            p->next=q->next;

        q=l->next;                /*输入整个链表前,先将q移到链表头,l一般不动*/
        while(q!=NULL)        /*若q所指向的元素后面还有其它元素,则将该元素的数据输出*/
        {
            printf("%c-->",q->c);    /*q->next->c表示q所指向的下一个元素的数据*/
            q=q->next;            /*完成该元素的输出后,q移至下一个元素重复输出操作*/
        }
    }

    //All copyright are preserved bycobby
    /*按位置删除元素*/

    #define NULL 0            /*宏定义*/
    typedef struct node        /*定义结点类型的数据结构*/
    {
        char c;            /*数据域,类型为字符型*/
        struct node *next;    /*指针域,类型为本结构体类型*/
    }Node,*L;            /*类型重定义,即Node和*L和struct node等价*/

    main()
    {
        L l,p,q;        /*用指针类型定义三个结点类型的指针*/
        char ch;
        int pos,n;
        l=(L)malloc(sizeof(Node));    /*分配内存空间*/
        l->c='\0';            /*为头结点的数据域赋值,值为空*/
        l->next=NULL;            /*指明下一个结点目前不存在*/
        q=l;                /*q为游动指针,链表结点的连结要用*/
        printf("Input a character:\n");
        scanf("%c",&ch);
        getchar();
        while(ch!='!')            /*输入!表示输入结束*/
        {
            p=(L)malloc(sizeof(Node));    /*为新输入的数据分配内存空间*/
            p->c=ch;
            p->next=NULL;            /*新输入的结点在链表的最后,即它的后面没有其它元素*/
            q->next=p;            /*q用于将上一个元素链接至当前新元素*/
            q=p;                /*q自己移到当前最后一个元素,以备继续链接所用*/
            scanf("%c",&ch);
            getchar();
        }
        q=l;                /*输入整个链表前,先将q移到链表头,l一般不动*/
        while(q->next!=NULL)        /*若q所指向的元素后面还有其它元素,则将该元素的数据输出*/
        {
            printf("%c-->",q->next->c);    /*q->next->c表示q所指向的下一个元素的数据*/
            q=q->next;            /*完成该元素的输出后,q移至下一个元素重复输出操作*/
        }

        /*以上为建立单链表*/

        printf("Input the position\n");
        scanf("%d",&pos);
        p=l;
        n=1;
        while(p->next!=NULL&&n!=pos)
        {
            p=p->next;
            n++;
        }
        /*退出循环后,可能找到删除的元素位置,可能表读完,需要进一步判断*/
        if(n==pos)    /*删除位置找到,删除该位置上的元素*/
        {
            p->next=p->next->next;
            //free(p);
        }
        else
            printf("incorrect position, delete failed\n");

        q=l;                /*输入整个链表前,先将q移到链表头,l一般不动*/
        while(q->next!=NULL)        /*若q所指向的元素后面还有其它元素,则将该元素的数据输出*/
        {
            printf("%c-->",q->next->c);    /*q->next->c表示q所指向的下一个元素的数据*/
            q=q->next;            /*完成该元素的输出后,q移至下一个元素重复输出操作*/
        }
    }

    //建立双向链表

    #include<stdio.h>
    #include<malloc.h>
    #include<stdlib.h>

    #define NULL 0

    typedef struct dlnode
    {
        char ch;
        struct dlnode *pri,*next;
    }dnode,*dl;

    main()
    {
        dl l,p,q;
        char c;
        l=(dl)malloc(sizeof(dnode));
        l->ch='\0';
        l->next=NULL;
        l->pri=NULL;
        q=l;

        printf("输入字符建立双向链表\n");
        scanf("%c",&c);
        getchar();
        
        while(c!='!')
        {
            p=(dl)malloc(sizeof(dnode));
            p->ch=c;
            p->pri=q;
            p->next=NULL;
            q->next=p;
            q=p;
            scanf("%c",&c);
            getchar();
        }
        q=l;
        while(q->next!=NULL)
        {
            q=q->next;
            printf("%c-->",q->ch);
        }
        
        printf("\n");
        while(q->pri!=NULL)
        {
            printf("%c-->",q->ch);
            q=q->pri;
        }
        printf("\n");
    }

  • 相关阅读:
    重载的概念和体现形式
    构造方法的概述和使用
    可变长参数
    成员方法的定义
    Point类的定义
    Person类的定义
    类和对象以及引用的定义
    高数学习----微积分
    高数学习----向量代数和空间解析几何
    一个无法解析的外部命令and无法解析的外部符号
  • 原文地址:https://www.cnblogs.com/shuzhengyi/p/1557582.html
Copyright © 2011-2022 走看看