线性表的合并:线性表的合并可以看成是两个集合,其中可以重复元素,当两个集合中有相同元素的时候,合并完成之后的表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;
}