Bootstrap

线性表->顺序表进阶操作

线性表的合并:线性表的合并可以看成是两个集合,其中可以重复元素,当两个集合中有相同元素的时候,合并完成之后的表c值能含有一个重复元素。
算法实现:以表b中的一个元素作为哨兵,遍历表a中的所有元素,如果a中没有出现与哨兵相同的元素,那么将哨兵插入表a的末尾中去。

void ListUnion(SqList &La,SqList Lb)
{
    int La_len=ListLength(La);
    int Lb_len=ListLength(Lb);
    int e=0;
    for(int i=1;i<=Lb_len;i++)
    {
        GetElem(Lb,i,e);
        if(!LocateElem(La,e))
        {
            ListInsert_Sq(La,++La_len,e);
        }
    }
}

有序表的合并:已知La,Lb中的数据元素按值非递减有序排列,现在要求将La,Lb归并为一个新的线性表Lc,且Lc中的数据元素仍按值非递减有序排列的表,与线性表的合并不同的是,相同的元素可以在c中重复出现。
注:非递减的意思就是有可能存在两个元素的值相等。
算法步骤:创建一个空表c,选定任意一个表,以某一个表为基表,从中任意摘取元素,与另外一个表比较,然后把较小的表插入到表c的末尾,直到其中某一个表为空表为止。
实现代码如下:

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
#define ElemType int

typedef int Status;
typedef struct
{
    int *elem;
    int length;
    int listsize;
}SqList;

Status InitList_Sq(SqList &L)
{  // 算法2.3
  // 构造一个空的线性表L。
  L.elem = (ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
  if (!L.elem) return OK;        // 存储分配失败
  L.length = 0;                  // 空表长度为0
  L.listsize = LIST_INIT_SIZE;   // 初始存储容量
  return OK;
} // InitList_Sq

Status ListInsert_Sq(SqList &L, int i, ElemType e)
{  // 算法2.4
  // 在顺序线性表L的第i个元素之前插入新的元素e,
  // i的合法值为1≤i≤ListLength_Sq(L)+1
  ElemType *p;
  if (i < 1 || i > L.length+1) return ERROR;  // i值不合法
  if (L.length >= L.listsize) {   // 当前存储空间已满,增加容量
    ElemType *newbase = (ElemType *)realloc(L.elem,
                  (L.listsize+LISTINCREMENT)*sizeof (ElemType));
    if (!newbase) return ERROR;   // 存储分配失败
    L.elem = newbase;             // 新基址
    L.listsize += LISTINCREMENT;  // 增加存储容量
  }
  ElemType *q = &(L.elem[i-1]);   // q为插入位置
  for (p = &(L.elem[L.length-1]); p>=q; --p) *(p+1) = *p;
                                  // 插入位置及之后的元素右移
  *q = e;       // 插入e
  ++L.length;   // 表长增1
  return OK;
} // ListInsert_Sq

Status ListDelete_Sq(SqList &L, int i, ElemType &e)
{  // 算法2.5
  // 在顺序线性表L中删除第i个元素,并用e返回其值。
  // i的合法值为1≤i≤ListLength_Sq(L)。
  ElemType *p, *q;
  if (i<1 || i>L.length) return ERROR;  // i值不合法
  p = &(L.elem[i-1]);                   // p为被删除元素的位置
  e = *p;                               // 被删除元素的值赋给e
  q = L.elem+L.length-1;                // 表尾元素的位置
  for (++p; p<=q; ++p) *(p-1) = *p;     // 被删除元素之后的元素左移
  --L.length;                           // 表长减1
  return OK;
} // ListDelete_Sq

void MergeList_Sq(SqList LA,SqList LB,SqList &LC)
{
    ElemType *pa=LA.elem;
    ElemType *pb=LB.elem;
    LC.length=LA.length+LB.length;//其长度变为两个合并的表长之和
    LC.elem=new ElemType[LC.length];//为新表创立一个内存空间
    ElemType *pc=LC.elem;//pc指向表c对应的内存空间
    ElemType *pa_last=LA.elem+LA.length-1;//基地址+地址长度
    ElemType *pb_last=LB.elem+LB.length-1;
    while(pa<=pa_last&&pb<=pb_last)
    {
        if(*pa<=*pb)//当表a的值比较小的时候,把a中的元素插入c的末尾,并且这个时候两个位置同时++
        {
            *pc++=*pa++;
        }
        else
        {
            *pc++=*pb++;
        }
    }
    //接下来是两个都有剩余或者两个都没剩余的情况
    while(pa<=pa_last)
    {
        *pc++=*pa++;
    }
    while(pb<=pb_last)
    {
        *pc++=*pb++;
    }
}

Status IntList_Sq(SqList &L)
{
    int listlength=0;
    scanf("%d",&listlength);
    int i,t;
    for(i=0;i<listlength;i++)
    {
        scanf("%d",&t);
        L.elem[i]=t;
        L.length++;
    }
    return OK;
}

Status LoadList_Sq(SqList &L)
{
    int i;
    for(i=0;i<L.length;i++)
    {
        printf("%d ",L.elem[i]);
    }
    printf("\n");
    return OK;
}

int main()
{
    SqList LA,LB,LC;
    InitList_Sq(LA);
    InitList_Sq(LB);
    InitList_Sq(LC);
    IntList_Sq(LA);
    printf("List A:");
    LoadList_Sq(LA);
    IntList_Sq(LB);
    printf("List B:");
    LoadList_Sq(LB);
    MergeList_Sq(LA,LB,LC);
    printf("List C:");
    LoadList_Sq(LC);
    return 0;
}

顺序表的逆置
设有一顺序表A=(a0,a1,…, ai,…an-1),其逆顺序表定义为A’=( an-1,…, ai,…,a1, a0)。设计一个算法,将顺序表逆置,要求顺序表仍占用原顺序表的空间。
代码如下:

#include<stdio.h>
#include<malloc.h>
#define OK 1
#define ERROR 0
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
#define ElemType int

typedef int Status;
typedef struct
{
    int *elem;
    int length;
    int listsize;
}SqList;

Status InitList_Sq(SqList &L)
{  // 算法2.3
  // 构造一个空的线性表L。
  L.elem = (ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
  if (!L.elem) return OK;        // 存储分配失败
  L.length = 0;                  // 空表长度为0
  L.listsize = LIST_INIT_SIZE;   // 初始存储容量
  return OK;
} // InitList_Sq

Status ListInsert_Sq(SqList &L, int i, ElemType e)
{  // 算法2.4
  // 在顺序线性表L的第i个元素之前插入新的元素e,
  // i的合法值为1≤i≤ListLength_Sq(L)+1
  ElemType *p;
  if (i < 1 || i > L.length+1) return ERROR;  // i值不合法
  if (L.length >= L.listsize) {   // 当前存储空间已满,增加容量
    ElemType *newbase = (ElemType *)realloc(L.elem,
                  (L.listsize+LISTINCREMENT)*sizeof (ElemType));
    if (!newbase) return ERROR;   // 存储分配失败
    L.elem = newbase;             // 新基址
    L.listsize += LISTINCREMENT;  // 增加存储容量
  }
  ElemType *q = &(L.elem[i-1]);   // q为插入位置
  for (p = &(L.elem[L.length-1]); p>=q; --p) *(p+1) = *p;
                                  // 插入位置及之后的元素右移
  *q = e;       // 插入e
  ++L.length;   // 表长增1
  return OK;
} // ListInsert_Sq

Status ListDelete_Sq(SqList &L, int i, ElemType &e)
{  // 算法2.5
  // 在顺序线性表L中删除第i个元素,并用e返回其值。
  // i的合法值为1≤i≤ListLength_Sq(L)。
  ElemType *p, *q;
  if (i<1 || i>L.length) return ERROR;  // i值不合法
  p = &(L.elem[i-1]);                   // p为被删除元素的位置
  e = *p;                               // 被删除元素的值赋给e
  q = L.elem+L.length-1;                // 表尾元素的位置
  for (++p; p<=q; ++p) *(p-1) = *p;     // 被删除元素之后的元素左移
  --L.length;                           // 表长减1
  return OK;
} // ListDelete_Sq

Status IntList_Sq(SqList &L)
{
    int listlength=0;
    scanf("%d",&listlength);
    int i,t;
    for(i=0;i<listlength;i++)
    {
        scanf("%d",&t);
        L.elem[i]=t;
        L.length++;
    }
    return OK;
}

Status LoadList_Sq(SqList &L)
{
    int i;
    for(i=0;i<L.length;i++)
    {
        printf("%d ",L.elem[i]);
    }
    printf("\n");
    return OK;
}

Status Inverse_Sq(SqList &L)
{
    int i=0,j=L.length-1;
    ElemType temp;
    while(i<j)
    {
       temp=L.elem[i];
       L.elem[i]=L.elem[j];
       L.elem[j]=temp;
       i++;
       j--;
    }
    return OK;
}

int main()
{
    SqList L;
    InitList_Sq(L);
    IntList_Sq(L);
    printf("The List is:");
    LoadList_Sq(L);
    Inverse_Sq(L);
    printf("The turned List is:");
    LoadList_Sq(L);
    return 0;
}

;