zoukankan      html  css  js  c++  java
  • 数据结构-----线性表的顺序表示与实现

    废话不多说,直接粘代码,一切尽在代码中。

    LIST.h当中代码:

    /* 
    * Copyright (c) 2014,个人所有
    * All rights reserved. 
    * 
    * 文件名称:LIST.h
    * 文件标识:见配置管理计划书
    * 摘  要:线性表的顺序存储
    * 
    * 当前版本:1.1
    * 作  者:zhuxuekui3
    * 完成日期:2014年5月4日
    * 
    * 取代版本:1.0 
    * 原作者  :zhuxuekui3
    * 完成日期:2014年5月3日
    */
    #ifndef LIST_H
    #define  LIST_H
    #include <iostream>
    using namespace std;
    //定义函数结果状态代码  
    #define TRUE        1  
    #define FALSE       0  
    #define OK          1  
    #define ERROR       0  
    #define OVERFLOW    -1  
    #define UNDERFLOW   -2  
    
    /********线性表的动态分配顺序存储结构******/
    const int LIST_INIT_SIZE = 100;
    const int LISTINCREMENT = 10;
    
    typedef int ElemType;
    typedef int Status;
    typedef bool (* comparePtr)(ElemType,ElemType);
    //comparePtr compare; //用comparePtr来申明全局compare变量
    typedef struct SqList
    {
        ElemType *elem; //存储空间基址 , 数组指针elem指示线性表的基地址。数组首地址
        int length;    //当前长度,记录数组的长度
        int listsize; //当前分配的存储容量(以sizeof(ElemType)为单位)
    } SqList;
    
    //初始化顺序表
    Status InitList_Sq(SqList &L);
    //在顺序表L中第i个位置之前插入新的元素e
    Status ListInsert_Sq(SqList &L,int i,ElemType e);
    //在顺序表L中第i个位置删除元素e,并用e返回其值
    Status ListDelete_Sq(SqList &L,int i,ElemType &e); //改.C文件的同时必须改声明
    //将顺序表中的元素输出
    Status ListPrint_Sq(SqList &L);
    //对无序的两个顺序表求并集
    void union1(SqList &La, SqList &Lb);
    
    void union2(SqList &La, SqList &Lb);
    
    bool equal(ElemType a, ElemType b);
    
    //在顺序表中查找与e相同的元素,并返回e所在的位置
    //int LocateElem_Sq(SqList &L,ElemType e,bool (* compare)(ElemType,ElemType));
    
    int LocateElem_Sq(SqList &L,ElemType e,comparePtr compare);
    
    //取顺序表中第i个元素赋给e
    Status GetElem(SqList &L,int i,ElemType &e);
    //好像对不需要传回来的数据,并不需要用引用,用形参就可以了
    void MergeList_Sq(SqList La,SqList Lb,SqList &Lc);
    
    #endif 

     LIST.cpp代码:

    /* 
    * Copyright (c) 2014,个人所有
    * All rights reserved. 
    * 
    * 文件名称:LIST.cpp
    * 文件标识:见配置管理计划书
    * 摘  要:线性表的顺序存储
    * 
    * 当前版本:1.1
    * 作  者:zhuxuekui3
    * 完成日期:2014年5月4日
    * 
    * 取代版本:1.0 
    * 原作者  :zhuxuekui3
    * 完成日期:2014年5月3日
    */
    #include "stdafx.h"
    #include "LIST.h"
    int main()
    {
        ElemType e;
        SqList L;
        SqList L1;
        SqList L2;//无需要初始化,会在函数当中初始化
        InitList_Sq(L);
        InitList_Sq(L1);
        //InitList_Sq(L2);
        ListInsert_Sq(L,1,9);
        ListInsert_Sq(L,2,7);
        ListInsert_Sq(L,3,4);
        ListInsert_Sq(L,4,2);
        ListPrint_Sq(L);
    
        ListInsert_Sq(L1,1,8);
        ListInsert_Sq(L1,2,6);
        ListInsert_Sq(L1,3,5);
        ListInsert_Sq(L1,4,3);
    
        ListPrint_Sq(L1);
    
        MergeList_Sq(L,L1,L2);
        //union2(L,L1);
        //ListDelete_Sq(L,1,e);
        //cout << e << endl;
        ListPrint_Sq(L2);
        return 0;
    }
    
    //初始化线性表
    Status InitList_Sq(SqList &L)
    {
       L.elem = (ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
       if (!L.elem)
       {
           exit(OVERFLOW);  
       }
       L.length = 0;                //空表的长度为0
       L.listsize = LIST_INIT_SIZE; //初始存储容量
       return OK;
    }
    
    //在顺序表L中第i个位置之前插入新的元素e
    Status ListInsert_Sq(SqList &L,int i,ElemType e)
    {
        //  1<=i<=L.length + 1; 有效范围
       if(i<1 || i>L.length + 1) return ERROR;
       if (L.length > L.listsize)//当前分配的内存已满,已int为一个单位,需要重新开辟内存空间
       {
           ElemType* newbase = (ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
           if (!newbase)//分配未成功
           {
               exit(OVERFLOW);
           }
           L.elem = newbase;//new address
           L.listsize += LISTINCREMENT;// add store memery
       }
    
       ElemType * q = &(L.elem[i-1]);
       ElemType * p = &(L.elem[L.length - 1]);  //这里可以改为 = L.elem + L.length - 1;
       for (p; p >= q; --p)    //一直循环到p = q为止
       {
           *(p+1) = *p;      //小下标的数,返回给大下标的数
       }
       *q = e;               //插入e;
       ++L.length;           //表长加1;
       return OK;
    }
    
    
    Status ListDelete_Sq(SqList &L,int i,ElemType &e)
    {
        if(i<1 || i>L.length + 1) return ERROR;
        ElemType *q = &(L.elem[i-1]);
        ElemType *p = &(L.elem[L.length-1]);
        e = *q;
        for (q;q<=p;++q)   //将下标大的数赋值给下标小的数
        {
           *q = *(q+1);
        }
       --L.length;
       return OK;
    }
    
    Status ListPrint_Sq(SqList &L)
    {
       ElemType *p = &(L.elem[0]);
       ElemType *q = &(L.elem[L.length-1]);
       for (p;p<=q;++p)
       {
           cout << *p << "  ";
       }
       cout << endl;
       return OK;
    }
    
    //对无序的两个顺序表求并集
    /*
       有两种思路,要么重新开辟一个Lc,然后将两者插入进去,不允许重复。但操作这种方法时候,
       要求我们先排序。这样操作才方便些。时间复杂度Length(La)+Length(Lb).
       或者,我们用控制变量法,这种方法时间复杂度Length(La)*Length(Lb).
       说白了,就是以空间换时间,或者以时间换空间,别无其他。
    */
    //时间复杂度Length(La)*Length(Lb),节省了空间。
    //下面语句是提取相同的元素到La中去,不是求并集,切记。
    void union1(SqList &La, SqList &Lb)
    {
       ElemType *q1 = &(La.elem[0]);
       ElemType *p1 = &(La.elem[La.length-1]);
       
       ElemType *q2 = &(Lb.elem[0]);
       ElemType *p2 = &(Lb.elem[Lb.length-1]);
       ElemType *temp = q2; //这里面是用的常量在初始化,并不是用变量在初始化指针。
    
       int count = 1;
       /*下面的语句,用&(La.elem[La.length-1]),不可用p1,p1是不变的,而我们插入的话
         La是在变动的,所以不可以用一个不变的东西去代替。但p2是不变的,无所谓。
       */
       for(q1; q1<= &(La.elem[La.length-1]); ++q1)
       {       
           for (q2;q2<=p2;++q2)
           {
               if (*q1==*q2)
               {
                  ListInsert_Sq(La,count,*q1);
                  ++q1;     //注意:La是在变动的。
                  ++count; //严格控制插入的位置,La在变,指针位置相对的移动一个位置,所以
                          //与La相关的count也是需要变动的。
               }
           }
           q2 = temp;
           ++count;
       }
    }
    //将所有在Lb中但不在La中的数据元素插入到La中去
    void union2(SqList &La, SqList &Lb)
    {
       int La_Len = La.length;
       int Lb_Len = Lb.length;
       ElemType e = 0;
       for (int i = 1; i <= Lb_Len; ++i)
       {
           GetElem(Lb,i,e);//取Lb中的第i个数据元素赋给e
           if (!LocateElem_Sq(La,e,equal))//La中不存在和e相同的元素,则插入
           {
              ListInsert_Sq(La,++La_Len,e);
           }
       }
    }
    
    //在顺序表中查找与e相同的元素,并返回e所在的位置 comparePtr compare
    //int LocateElem_Sq(SqList &L,ElemType e,bool (* compare)(ElemType,ElemType))
    int LocateElem_Sq(SqList &L,ElemType e,comparePtr compare)
    {
        //若找到,则返回其在L中的位置,否则返回0;
        int i = 1;
        ElemType *p = L.elem;//第一个元素的位置
        while(i <= L.length && !(compare(*p++,e))) ++i; //这里通过compare指针来执行传递过来的函数
        if (i <= L.length)                 //注意:compare所指的函数是有一个参数的。
        {
            return i;
        }
        else
        {
            return 0;
        }
    }
    
    Status GetElem(SqList &L,int i,ElemType &e)
    {
        if(i<1 || i>L.length + 1) 
        return ERROR;
        e = L.elem[i-1];
        return OK;
    }
    
    bool equal(ElemType a, ElemType b)
    {
        if (a == b)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    
    //已知顺序表中La与Lb有序,归并
    void MergeList_Sq(SqList La,SqList Lb,SqList &Lc)
    {
       ElemType *pa = La.elem;
       ElemType *pa_last = La.elem + La.length - 1;
    
       ElemType *pb = Lb.elem;
       ElemType *pb_last = Lb.elem + Lb.length - 1;
    
       Lc.length = La.length + Lb.length;
       Lc.listsize = Lc.length;//数组的长度
       Lc.elem = (ElemType *)malloc(Lc.listsize*sizeof(ElemType));//数组的容量
       if (!Lc.elem) //内存分配失败 ,即返回0,!之后就变成真了。
       {
           exit(OVERFLOW);
       }
       ElemType *pc = Lc.elem;
    
       while(pa <= pa_last && pb <= pb_last)  //降序排列
       {
           if (*pa < *pb)
           {
               *pc++ = *pb++;  //pc是需要移动的
           }
           else if (*pa == *pb)
           {
               *pc++ = *pa++;
               pb++;
           }
           else
           {
               *pc++ = *pa++;
           }
    
       }
       while(pa <= pa_last)  *pc++ = *pa++;
       while(pb <= pb_last)  *pc++ = *pa++;
       
    }
  • 相关阅读:
    约数的问题
    广度搜索基本逻辑
    奇葩概念
    一枚前端UI组件库 KUI for React
    一枚前端UI组件库 KUI for Vue
    跨域的常见问题和解决方案
    Comet,SSE,WebSocket前后端的实现
    web渐进式应用PWA
    IIS 部署node
    javascript 时间戳
  • 原文地址:https://www.cnblogs.com/zhuxuekui/p/3707390.html
Copyright © 2011-2022 走看看