数据结构-----线性表的顺序表示与实现

 

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

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++;
   
}

 

posted on 2014-05-04 16:42  zhuxuekui3  阅读(394)  评论(0编辑  收藏  举报