线性表是最常见且最简单的一种数据结构,简而言之一个线性表是n个数据元素的有限序列
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<time.h>
//---------线性表的动态分配顺序存储结构-----------
#define LIST_INIT_SIZE 50
#define LIST_INCREASE 10
typedef int ElemType; //重命名,方便管理
typedef struct SeqList
{
ElemType *elem; //存储空间基址
int length; //当前长度
int capacity; //当前分配的容量以(sizeof(ElemType))为单位
}SeqList;
void Init_SeqList(SeqList *L); //初始化顺序表
void Insert_SeqList(SeqList *L, ElemType x, int pos); //按位置插入
ElemType DeleteLoc_SeqList(SeqList *L, int pos); //按位置删除,并返回删除的值
int LocateElem_SeqList(SeqList *L, ElemType x); //查找数据,返回位置下标
void Merge_SeqList(SeqList *La, SeqList *Lb, SeqList *Lc); //按非递减顺序合并顺序表La、Lb
void Sort(SeqList *L);//以非递减序列给顺序表排序(另一种选择排序法)
分类实现各种功能
一、初始化顺序表:
//初始化顺序表
void Init_SeqList(SeqList *L)
{
L->elem = (ElemType*)malloc(sizeof(ElemType)*LIST_INIT_SIZE);
assert(L->elem != NULL); //断言
L->length = 0;
L->capacity = LIST_INIT_SIZE;
}
二、按位置插入顺序表
//按位置插入
void Insert_SeqList(SeqList *L, ElemType x, int pos)
{
if (pos<0 || pos>L->length + 1) //判断合法性
{
printf("插入位置非法...\n");
return;
}
if (L->length >= L->capacity) //存储空间满,增加分配
{
L->elem = (ElemType*)realloc(L->elem, (L->capacity + LIST_INCREASE)*sizeof(ElemType));
assert(L->elem != NULL);
L->capacity = L->capacity + LIST_INCREASE;
}
for (int i = L->length ; i > pos; i--)
{
L->elem[i] = L->elem[i - 1]; //插入位置后的所有元素依次后移
}
L->elem[pos] = x; //插入数据
L->length++;
}
三、按位置删除对应的数据,并返回其值
//按位置删除,并返回删除的值
ElemType DeleteLoc_SeqList(SeqList *L, int pos)
{
if (pos<0 || pos>L->length + 1) //判断合法性
{
printf("删除位置非法...\n");
return -1;
}
int x = L->elem[pos];
for (int i = pos; i < L->length - 1; i++)
{
L->elem[i] = L->elem[i+1]; //从删除位置开始以后一元素依次覆盖前面的元素
}
L->length--;
return x;
}
四、查找相应数据的位置
//定位查找数据
int LocateElem_SeqList(SeqList *L, ElemType x)
{
int i = 0;
while (i <= L->length && L->elem[i] != x)
{
i++;
}
if (i <= L->length){
return i;
}
else
return -1;
}
五、按非递减排序
//以非递减序列给顺序表排序(另一种选择排序法)
void Sort(SeqList *L)
{
int a = 0;
int b = L->length - 1;
while (a < b)
{
int max = a;
int min = a;
for (int i = a; i <= b; i++)
{
if (L->elem[min] > L->elem[i])
{
min = i;
}
if (L->elem[max] < L->elem[i])
{
max = i;
}
}
if (L->elem[a] > L->elem[min])
{
int temp = L->elem[a];
L->elem[a] = L->elem[min];
L->elem[min] = temp;
}
if (max == a)
{
max = min;
}
if (L->elem[b] < L->elem[max])
{
int temp = L->elem[b];
L->elem[b] = L->elem[max];
L->elem[max] = temp;
}
a++, b--;
}
}
六、按非递减合并两个顺序表
//按非递减顺序合并顺序表La、Lb
void Merge_SeqList(SeqList La, SeqList Lb, SeqList *Lc)
{
Sort(&La), Sort(&Lb); //先将两个顺序表按非递减排序
int i = 0, j = 0, z = 0;
Lc->length = La.length + Lb.length;
Lc->elem = (ElemType*)realloc(Lc->elem, sizeof(ElemType)*(La.length + Lb.length));
assert(Lc->elem != NULL); //分配失败
while (i < La.length&&j < Lb.length)
{
if (La.elem[i] >= Lb.elem[j]) //插小的
{
Lc->elem[z++] = Lb.elem[j++];
}
else
{
Lc->elem[z++] = La.elem[i++];
}
}
while (i < La.length){ //插入La剩余元素
Lc->elem[z++] = La.elem[i++];
}
while (j < Lb.length){ //插入Lb剩余元素
Lc->elem[z++] = Lb.elem[j++];
}
}
以下是用于测试的主函数:
int main()
{
SeqList L,L1,L2;
Init_SeqList(&L);
Init_SeqList(&L1);
Init_SeqList(&L2);
for (int i = 0; i < 8; i++) //随机赋值0--15
{
L1.elem[i] = rand() % 16;
L1.length++;
}
for (int i = 0; i < 8; i++) //随机赋值0--15
{
L2.elem[i] = rand() % 16;
L2.length++;
}
printf("顺序表L1:");
for (int i = 0; i < L1.length; i++) //输出顺序表L1
{
printf("%d ", L1.elem[i]);
}
printf("\n\n顺序表L2:");
for (int i = 0; i < L2.length; i++) //输出顺序表L2
{
printf("%d ", L2.elem[i]);
}
printf("\n\n将12插入L1顺序表的3号位置:"); //按位置插入
Insert_SeqList(&L1, 12, 3);
for (int i = 0; i < L1.length; i++)
{
printf("%d ", L1.elem[i]);
}
printf("\n\n删除L1顺序表数值为5的元素:"); //删除指定元素
int val;
val = DeleteLoc_SeqList(&L1, 5);
for (int i = 0; i < L1.length; i++)
{
printf("%d ", L1.elem[i]);
}
printf("\n对应位置为(-1表示无此元素):%d\n", val);
val = LocateElem_SeqList(&L1, 5);
printf("查找下标位置为5的元素为(-1表示无此元素):%d\n\n", val);
printf("非递减合并:");
Merge_SeqList(L1, L2, &L); //非递减合并
for (int i = 0; i < L.length; i++)
{
printf("%d ", L.elem[i]);
}
system("pause");
return 0;
}
其结果为: