顺序表的概念:
顺序表是指用一组地址连续的存储单元依次存储线性表中的各个元素,使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系。
简单的实现方式:
#include<stdio.h>
#include<stdlib.h>
#define INIT_SQ_SIZE 100
#define LIST_INCREMENT 10
typedef struct{
int *elem;
int length;
int listSize;
}SqList;
//初始化顺序表
int InitSqList(SqList *L)
{
L->elem = (int *)malloc(INIT_SQ_SIZE*sizeof(int));
if (L->elem == NULL)
return -1;
L->length = 0;
L->listSize = INIT_SQ_SIZE;
return 0;
}
//创建顺序表
void CreatSqList(SqList *L)
{
int i = 1, x;
printf("输入线性表的元素(Enter+ctrl+z)结束\n");
while (scanf("%d", &x) != EOF)
{
InsertSqList(L, i, x);
i++;
}
}
//在顺序表指定位置i,插入元素e
int InsertSqList(SqList *L, int i, int e)
{
int *newElem,*p,*q;
if (i<1 || i>L->length + 1)
{
return -1;
}
if (L->length >= L->listSize)
{//继续申请内存
newElem = (int *)realloc(L->elem, (INIT_SQ_SIZE + LIST_INCREMENT)*sizeof(int));
if (newElem == NULL)
return -1;
L->elem = newElem;
L->listSize += LIST_INCREMENT;
}
q = &(L->elem[i - 1]);
for (p = &(L->elem[L->length - 1]); p >= q; p--)
{//后移
*(p + 1) = *(p);
}
*q = e;
L->length++;
return 0;
}
//删除顺顺序表中i位置的元素
int DeleteSqList(SqList *L, int i)
{
int *p, *q;
if (i<1 || i>L->length)
{
return -1;
}
p = &L->elem[i - 1];//指向要删除的位置
q = &L->elem[L->length - 1];
//前移
for (++p; p <= q; ++p)
{
*(p - 1) = *(p);
}
L->length--;
return 0;
}
//删除值为x的元素
int DeletexSqList(SqList *L, int x)
{
int i =0;
int *p, *q;
p = L->elem;
while ((i < L->length) && *p != x)
{
p++;
i++;
}
if (i == L->length)
{
return -1;
}
else
{
q = &L->elem[L->length - 1];
for (++p; p <= q; p++)
{
*(p - 1) = *(p);
}
L->length--;
return 0;
}
}
//将顺序表逆置结果保存在另一个顺序表中
void NiZhiSqList(SqList La, SqList *Lb)
{
int i;
Lb->length = La.length;
for (i = 0; i < La.length; i++)
{
Lb->elem[Lb->length - 1 - i] = La.elem[i];
}
}
void MergeSqList(SqList La,SqList Lb,SqList *Lc)
{
int *pa, *pb, *pc, *pa_last, *pb_last;
pc = NULL;
pa = La.elem;
pb = Lb.elem;
Lc->listSize = Lc->length = La.length + Lb.length;
pc = Lc->elem = (int *)malloc(Lc->listSize*sizeof(int));
if (pc == NULL)
{
return;
}
pa_last = &La.elem[La.length - 1];
pb_last = &Lb.elem[Lb.length - 1];
while (pa <= pa_last&&pb <= pb_last)
{
if (*pa <= *pb)
{
*pc++ = *pa++;
}
else
{
*pc++ = *pb++;
}
}
while (pa <= pa_last)
{
*pc++ = *pa++;
}
while (pb <= pb_last)
{
*pc++ = *pb++;
}
}
//输出顺序表
void Myprintf_Sq(SqList L)
{
int i;
printf("线性表的长度:%d\n", L.length);
for (i = 0; i < L.length; i++)
{
printf("%4d", L.elem[i]);
}
printf("\n");
}
int main()
{
SqList La,Lb,Lc;
int i,x, flag,menu,m;
do
{
printf("1:建立一个顺序表\n");
printf("2:输出顺序表及顺序表的长度\n");
printf("3:在顺序表给定的位置i插入值为x的元素\n");
printf("4:在顺序表中删除值为x的元素或者删除给定位置i的节点\n");
printf("5:将顺序表逆置,将结果保存在另外的顺序表中\n");
printf("6:将两个顺序有序表A和B合并为一个有序表C\n");
printf("0:退出\n");
scanf("%d", &menu);
switch (menu)
{
case 1:
InitSqList(&La);
CreatSqList(&La);
break;
case 2:
Myprintf_Sq(La);
break;
case 3:
printf("请输入要插入的元素的位置i和插入元素值x:(1<=i<=%d)\n", La.length + 1);
scanf("%d%d", &i, &x);
flag = InsertSqList(&La, i, x);
if (flag < 0)
{
printf("插入失败!!\n");
}
else
{
printf("插入成功!!\n");
Myprintf_Sq(La);
}
break;
case 4:
printf("选择删除方式:1删除值为x的节点 2删除第i个节点\n");
scanf("%d", &m);
if (1 == m)
{
printf("请输入要删除的元素x\n");
scanf("%d", &x);
flag = DeletexSqList(&La, x);
if (flag < 0)
{
printf("删除失败!!\n");
}
else
{
printf("删除成功!!\n");
}
Myprintf_Sq(La);
}
else if (2 == m)
{
printf("请输入要删除的位置\n");
scanf("%d", &i);
flag = DeleteSqList(&La, i);
if (flag < 0)
{
printf("删除失败!!\n");
}
else
{
printf("删除成功!!\n");
}
Myprintf_Sq(La);
}
else
{
printf("选择有误!!\n");
}
break;
case 5:
InitSqList(&Lb);
NiZhiSqList(La, &Lb);
printf("逆置前的顺序表:\n");
Myprintf_Sq(La);
printf("逆置后的顺序表:\n");
Myprintf_Sq(Lb);
break;
case 6:
InitSqList(&La);
InitSqList(&Lb);
InitSqList(&Lc);
CreatSqList(&La);
CreatSqList(&Lb);
MergeSqList(La, Lb, &Lc);
printf("合并前的顺序表:\n");
Myprintf_Sq(La);
Myprintf_Sq(Lb);
printf("合并后的顺序表:\n");
Myprintf_Sq(Lc);
break;
case 0:
exit(0);
default:
break;
}
} while (menu);
return 0;
}