主要是想实现数据结构教材–算法2.1 例2.2
将La={3,5,8,11},Lb={2,6,8,9,11,15,20}合并(将存在于Lb中的元素但是不存在与La中的元素插入Lb中)
增加了几个常用操作的实现。
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
#define OVERFELOW -1
typedef bool Status;
//定义结构体类型,可以看成是一种数据类型,名字叫做SqList
//该数据类型,含有三个成员,pBase,length,Listsize。
struct SqList
{
int *pBase; //第一个元素的首地址
int length; //当前元素个数
int Listsize; //当前链表长度
};
Status InitList_Sq(SqList &L,int number);
void InputList(SqList &L,int number);
int ListLength(SqList L);
void union_La_Lb(SqList &La,SqList &Lb);
Status GetElem(SqList L,int pos,int &e);
Status LocateElem(SqList L,int e);
Status ListInsert(SqList &L,int i,int e);
void ClearList(SqList &L);
void IsEmpty(SqList L);
Status ListDeleted(SqList &L,int i,int &k);
void OutputList(SqList L,int number);
int main (void)
{
struct SqList La,Lb;//定义SqList类型的链表La,Lb
int K;
InitList_Sq(La,4); //调用函数InitList_SqList对链表La,Lb进行初始化操作
InitList_Sq(Lb,7); //顺序表La,Lb含有元素个数分别为10,5个
InputList(La,La.Listsize); //给La,Lb赋值。
InputList(Lb,Lb.Listsize);
int La_len_AfterInput = ListLength(La); //求La,Lb当前元素长度
int Lb_len_AfterInput = ListLength(Lb);
OutputList(La,La_len_AfterInput ); //输出La,Lb
OutputList(Lb,Lb_len_AfterInput);
union_La_Lb(La,Lb); //合并La,Lb
int La_len_AfterUnion = ListLength(La); //求La,Lb当前元素长度
int Lb_len_AfterUnion = ListLength(Lb);
OutputList(La,La_len_AfterUnion); //输出La,Lb
OutputList(Lb,Lb_len_AfterUnion);
ClearList(Lb); //清空Lb
IsEmpty(Lb); //判断是否为空
int La_len_AfterClear = ListLength(La);
int Lb_len_AfterClear = ListLength(Lb);
OutputList(La,La_len_AfterClear); //输出La,Lb
OutputList(Lb,Lb_len_AfterClear);
ListDeleted(La,La_len_AfterClear-2,K); //删除倒数第三个元素
int La_len_AfterDelete = ListLength(La);
OutputList(La,La_len_AfterDelete); //输出La,Lb
OutputList(Lb,Lb_len_AfterClear);
return 0;
}
//定义初始化顺序表的函数InitList_Sq 1 2 3 4 5
Status InitList_Sq(SqList &L,int number)
{
L.pBase = (int *)malloc((number)*sizeof(int));
if(!L.pBase)
exit(OVERFELOW);
else
{
L.length = 0;
L.Listsize = number;
}
return 0;
}
//定义链表赋值函数
void InputList(SqList &L,int number)
{
for(int i=0;i<number;i++)
{
scanf("%d",&L.pBase[i]);
L.length++; //由于初始化之后当前元素个数被重置为了0,就需要每输入一个元素就length++
}
}
//定义求顺序表的长度的函数 ListLength
int ListLength(SqList L)
{
return (L.length);
}
//定义合并La,Lb的函数
void union_La_Lb(SqList &La,SqList &Lb)
{
int La_len = ListLength(La);
int Lb_len = ListLength(Lb);
for(int i=1;i<=Lb_len;i++)
{
int e;
GetElem(Lb,i,e);
if(!LocateElem(La,e))
{
ListInsert(La,++La_len,e);
}
}
}
//定义取值函数
Status GetElem(SqList L,int pos,int &e)
{
if(pos<1 || pos>L.length)
return ERROR;
else
{
e = L.pBase[pos-1];
return OK;
}
}
//定义按值查找函数
Status LocateElem(SqList L,int e)
{
for(int i=0;i<L.length;i++)
{
if(L.pBase[i] == e)
return true;
else
{//必须要满足Lb中元素与La中元素所有的都不同的时候才能插入。
int cnt = 0;
cnt++;
if(cnt == L.length)
{
return false;
}
continue;
}
}
}
//定义插入函数,这里是直接尾差。就不需要使用前插循环插入
Status ListInsert(SqList &L,int i,int e)
{
if(i<1 || i>L.length+1)
return ERROR;
if(L.length>= L.Listsize)
{
int *newbase = (int *)realloc(L.pBase,(L.Listsize+LISTINCREMENT)*sizeof(int));
if(!newbase)
exit (OVERFELOW); //判断是否分配成功
else
{
L.pBase = newbase; //新基地址
L.Listsize += LISTINCREMENT; //增加存储容量
}
}
//尾差法,算法描述
L.pBase[i-1] = e;
L.length++;
/*这是非尾插入法中的前插法的写法
int *q = &(L.pBase[i-1]);
for(int *p = &(L.pBase[L.length-1]);p>=q;p--)
{
*(p+1) = *p;
*q = e;
++L.length;
}*/
return OK;
}
//定义清空顺序表操作函数
void ClearList(SqList &L)
{
L.length = 0;
}
//定义判空操作函数
void IsEmpty(SqList L)
{
if(L.length == 0)
printf("empty!\n");
else
printf("no!\n");
}
//定义删除操作函数
Status ListDeleted(SqList &L,int i,int &k)
{
if(L.length == 0)
printf("没有元素可以删除!\n");
else if(i<1 || i>L.length)
printf("删除位置错误!\n");
else if(i<L.length)
{
k = L.pBase[i-1];
for(int j=i;j<L.length;j++)
{
L.pBase[j-1] = L.pBase[j];
}
L.length--;
}
else
L.length--;
}
//定义顺序表输出操作函数
void OutputList(SqList L,int number)
{
if(L.length == 0)
printf("List was cleared!");
for(int i=0;i<number;i++)
{
printf("%d ",L.pBase[i]);
}
printf("\n");
}
/*
输入:
3 5 8 11
2 6 8 9 16 20 11
输入之后两个顺序的输出
3 5 8 11
2 6 8 9 16 20 11
合并之后两个顺序的输出
3 5 8 11 2 6 9 16 20
2 6 8 9 16 20 11
清空后,判断是否为空
empty!
清空后两个顺序表的个元素
3 5 8 11 2 6 9 16 20
List was cleared!
删除La中倒数第三个元素后的输出
3 5 8 11 2 6 16 20
List was cleared!
*/