美文网首页
从0开始——线性表

从0开始——线性表

作者: c枫_撸码的日子 | 来源:发表于2018-11-06 20:16 被阅读0次

    一、ADT:抽象数据类型(abstract data type)

    之前学习过ADT的概念:其实就是数据+操作的集合,例如未来我们要学习到的[表、树、图],以及他们的相关的[操作]一起称之为抽象数据类型,未来学习以此展开!

    二、线性表

    1.定义
    0个或者多个数据元素的有限序列。

    2.线性表抽象数据类型 ADT
    线性表分顺序存储结构和链式存储结构,分别称为顺序表,链表

    ADT 线性表(SqList):顺序表
    Data
      线性表的数据对象集合为{a1,a2,...an},没个元素的类型均为DataType。
    Operation:
    InitList(L)    初始化线性表,建立一个空的线性表
    ListEmpty(*L)  判断线性表是否为空,空返回true
    ClearList(*L)  清空线性表
    GetElem(L,I,*e) 获取线性表L中的第i个元素给e
    LocateElem(L,e)在线性表L中查找元素e,若存在返回e的下标,否则返回0
    ListLength(L) 返回线性表的长度
    ListInsert(*L,i,e)在线性表L中的第i个位置插入新元素e
    ListDelete(*L,i,*e)删除线性表L中的第i个位置的元素,并用e返回其值
    
    

    3.顺序表的实现

    /*
    ADT:顺序表  
    */
    
    #include <stdio.h>;
    #include <windows.h>;
    
    #define MAXSIZE 20//顺序表的最大长度
    typedef int ElemType;//这里ElemType要根据实际需求去定义
    #define ERROR 0
    #define OK 1
    
    typedef struct 
    {
        ElemType data[MAXSIZE];//用数组存储线性表中的元素
        int len;//顺序表长度 
    } SqList;
    
    //初始化顺序表 
    void InitList(SqList *L)
    {
        printf("在init函数中 L=%x &L =%x *L =%x\n",L,&L,*L);
        if(L == NULL)
            return;
        (L)->len = 0;   
        printf("初始化线性表成功\n");   
    }
    //判断线性表是否为空,空返回true
    boolean ListEmpty(SqList *L)
    {
        if(L->len == 0)
        {
            printf("线性表为空\n");
            return 1;
        }
        else
        {
            printf("线性表 不为 空\n");
            return 0;       
        }   
    }
    //清空线性表
    ClearList(SqList *L)
    {
        printf("清空线性表\n");
        L->len = 0;         
    } 
    //获取线性表L中的第i个元素给e 
    int GetElem(SqList *L,int i,ElemType *e)
    {
        if(L->len==0 || i<0 || i> L->len)
            return ERROR;
        *e = L->data[i-1];
        printf("线性表L中的第%d个元素为%d\n",i,*e); 
        return OK;  
    }
    //在线性表L中查找元素e,若存在返回e的下标,否则返回0
    LocateElem(SqList *L,ElemType e)
    {
        int i;
        for(i=0; i < L->len; i++)
        {
            if(e == L->data[i])
            {
                printf("线性表L中的找到元素%d,下标为%d\n",e,i);
                return i;//返回下标 
            }
                
        }
        printf("线性表L中的找不到元素%d\n",e);
        return ERROR;//返回0 
    }
    //返回线性表的长度 
    int ListLength(SqList *L)
    {
        printf("线性表L的长度为%d\n",L->len);
        return L->len;
    } 
    //在线性表L中的第i个位置插入新元素e
    int ListInsert(SqList *L,int i,ElemType e)
    {
        int k;
        if(L->len== MAXSIZE)
        {
            printf("数组已满,插入失败\n");
            return ERROR;
        }
        if(i < 1 || i > L->len+1)
        {
            printf("插入位置有误\n");
            return ERROR;
        }
        for(k=L->len-1;k>=i-1;k--)
            L->data[k+1] = L->data[k];//元素往后移动
        L->data[i-1] = e; //插入元素 
        L->len++;//长度加1 
        return OK;
    }
    //删除线性表L中的第i个位置的元素,并用e返回其值
    int ListDelete(SqList *L,int i,ElemType *e)
    {
        int j; 
        if(i<1 || i>L->len)
        {
            printf("删除位置有误\n");
            return ERROR; 
        } 
        *e=L->data[i-1];//记录会删掉的元素 
        printf("删除掉的元素为%d\n",*e);
        for(j=i-1;j<L->len-1;j++)
        {
            L->data[j]=L->data[j+1];
        }
        L->len--;
        
        return OK;
    }
    //打印顺序表
    void show(SqList *L)
    {
        int i;
        for(i=0 ;i < L->len;i++)
            printf("%d ",L->data[i]);
        printf("\n");
    } 
    
    int main()
    {   
        SqList *L  = (SqList*)malloc(sizeof(SqList));;
        printf("分配之前L=%x &L =%x *L =%x \n",L,&L,*L);
        int i,temp;
        InitList(L);
        printf("分配之后 L=%x &L =%x *L =%x \n\n",L,&L,*L);
        for(i=1;i<=15;i++)
            ListInsert(L,i,i);  
        show(L);
        ListLength(L);
        GetElem(L,8,&temp);
        LocateElem(L,10);
        LocateElem(L,88);
        ListLength(L);
        ListEmpty(L);
        ListDelete(L,6,&temp);
        show(L);
        system("pause");
        return OK;
    }
    

    运行结果

    顺序表

    4.链表的实现

    /*
    ADT 线性表(SqList):链表
    Data
      线性表的数据对象集合为{a1,a2,...an},没个元素的类型均为DataType。
    Operation:
    InitList(L)    初始化线性表,建立一个空的线性表
    ListEmpty(*L)  判断线性表是否为空,空返回true
    ClearList(*L)  清空线性表
    GetElem(L,I,*e) 获取线性表L中的第i个元素给e
    LocateElem(L,e)在线性表L中查找元素e,若存在返回e的下标,否则返回0
    ListLength(L) 返回线性表的长度
    ListInsert(*L,i,e)在线性表L中的第i个位置插入新元素e
    ListDelete(*L,i,*e)删除线性表L中的第i个位置的元素,并用e返回其值
    */
    
    #include <stdio.h> 
    #include <windows.h>
    
    #define OK 1
    #define ERROR 0
    typedef int ElemType;//这里ElemType要根据实际需求去定义
    
    typedef struct Node
    {
        ElemType data;//保存数据
        struct Node * next; 
    }Node,*LinkList;//注意这里LinkList 是一个一级指针
    //初始化线性表,建立一个空的线性表
    LinkList InitList()
    {
        //创建头结点 
        LinkList head = (LinkList)malloc(sizeof(Node));
        if(head ==NULL)
        {
            printf("初始化失败\n"); 
            return NULL;
        }
        printf("初始化成功\n");
        head->data = 0;//头结点的data保存链表的长度
        head->next=NULL; 
        return head;
    }
    //判断线性表是否为空,空返回true 
    boolean ListEmpty(LinkList L)
    {
        if(L->next == NULL)
            printf("链表为空\n");
        else
            printf("链表不为空\n");
        return L->next ==NULL;  
    }
    //获取线性表L中的第i个元素给e 
    int GetElem(LinkList L,int i,ElemType *e)
    {
        LinkList p =L;//指向头结点
        int j =1;
        while(p->next != NULL && j<=i)
        {
            p=p->next;
            j++;
        }   
        if(p ==NULL || j>i+1 || j<=0)
        {
            printf("获取出错\n");
            return ERROR;   
        }
        printf("第%d个元素的值为%d\n",i,p->data);
        return OK;
            
    }
    //在线性表L中查找元素e,若存在返回e的下标,否则返回0
    int LocateElem(LinkList L,ElemType e)
    {
        LinkList p = L;//指向头结点
        int j=1;
        while(p->next != NULL)
        {
            if(p->next->data == e)
            {
                printf("元素%d在第%d个位置\n",e,j);
                return j;
            }
            p=p->next;
            j++;
        }
        printf("链表中不包含元素%d\n",e);
        return ERROR;   
    }
    //返回线性表的长度
    int ListLength(LinkList L) 
    {
        printf("链表长度为%d\n",L->data);
        return L->data; 
    }
    // 尾插法:在线性表L中的第i个位置插入新元素e
    int ListTailInsert(LinkList L,int i,ElemType e)
    {
        LinkList p=L,s;//p指向头结点 
        int j = 1;
        while(p->next !=NULL && j<i)
        {
            p= p->next;
            j++;
        }
        if(p == NULL || j>i)
        {
            printf("插入位置有误\n");
            return ERROR;
        }
        s = (LinkList)malloc(sizeof(Node));
        s->data = e;
        s->next = p->next;
        p->next = s;
        L->data++;//链表长度+1
        return OK;
            
    }
    //头插法
    int ListHeadInsert(LinkList L,ElemType e)
    {
        LinkList p = L;//指向头结点
        LinkList s = (LinkList)malloc(sizeof(Node));
        s->data = e;
        s->next = p->next;
        p->next = s;
        p->data++;//链表长度+1 
        return OK ; 
    } 
    //删除线性表L中的第i个位置的元素,并用e返回其值
    int ListDelete(LinkList L,int i,ElemType *e)
    {
        int j =1;
        LinkList p,q;   
        p = L;//指向头结点
        while(p->next!=NULL && j<i)
        {
            p=p->next;
            j++;
        } 
        if(p->next == NULL || j>i)
        {
            printf("删除位置有误!\n");
            return ERROR;
        }
        q=p->next;
        p->next = q->next;
        *e = q->data;
        L->data--;//链表长度-1
        free(q);
        printf("删除的节点为%d\n",*e);
        return OK; 
    }
    //清空顺序表 
    void ClearList(LinkList L)
    {
        LinkList p,q;
        p = L->next;//指向第一个节点
        while(p!=NULL)
        {
            q=p->next;
            free(p);
            p=q;
        }   
        L->next = NULL; 
    }
    
    //打印顺序表 
    void showList(LinkList L)
    {
        LinkList p=L;//指向头结点 
        
        while(p->next != NULL)
        {
            p=p->next;
            printf("%d ",p->data);  
        }
        printf("\n");
        ListLength(L);//输出链表长度
    }
    
    int main()
    {
        LinkList head = InitList();
        LinkList head2 = InitList();
        int i,t;
        printf("尾插法创建链表\n"); 
        for(i=1;i<16;i++)
            ListTailInsert(head,i,i);
        showList(head);
        printf("头插法创建链表\n"); 
        for(i=1;i<16;i++)
            ListHeadInsert(head2,i);        
        showList(head2);
        GetElem(head,7,&t); 
        LocateElem(head,13);
        LocateElem(head,20); 
        ListDelete(head,1,&t);
        showList(head);
        system("pause");
        return OK;
    }
    

    运行结果

    链表

    相关文章

      网友评论

          本文标题:从0开始——线性表

          本文链接:https://www.haomeiwen.com/subject/yescxqtx.html