我最近在学习顺序表中的一些收获,如下所示。
#include"common.h"
1.引入常用的库
#pragma once #include<stdio.h> #include<assert.h> #include<malloc.h> #include<stdbool.h>
#include"seqlist.h"
我们自己定义的顺序表的库它的增删查改,数据类型的定义,函数命名,函数实现都在这里
#pragma once
#include"common.h"
#define SeqList_ElemType int
#define SEQLIST_DEFAULT_SIZE 5
#define SEQLIST_INC_SIZE 3
typedef struct SeqList
{
SeqList_ElemType* base; //顺序表的空间指针
size_t capacity; //顺序表的容量
size_t size; //顺序表的元素个数
}SeqList;
//函数声明
void SeqListInit(SeqList* pst);
void SeqListPushBack(SeqList* pst, SeqList_ElemType x);
void SeqListPushFront(SeqList* pst, SeqList_ElemType x);
void SeqListPopBack(SeqList* pst);
void SeqListPopFront(SeqList* pst);
int SeqListFind(SeqList* pst, SeqList_ElemType key);
void SeqListDeleteByVal(SeqList* pst, SeqList_ElemType key);
int SeqListLength(SeqList* pst);
int SeqListCapacity(SeqList* pst);
void SeqListInsertByPos(SeqList* pst, int pos, SeqList_ElemType x);
void SeqListInsertByVal(SeqList* pst, SeqList_ElemType x);
void SeqListDeleteByPos(SeqList* pst, int pos);
void SeqListClear(SeqList* pst);
void SeqListReverse(SeqList* pst);
void SeqListSort(SeqList* pst);
void SeqListShow(SeqList* pst);
void SeqListDestroy(SeqList* pst);
//辅助函数
//判断是否满
bool _SeqListIsFull(SeqList* pst)
{
assert(pst != NULL);
return pst->size >= pst->capacity;
}
//判断是否空
bool _SeqListIsEmpty(SeqList* pst)
{
assert(pst != NULL);
if (pst->size == 0)
return 1;
else
return 0;
}
bool _SeqListInc(SeqList* pst) //开辟空间
{
assert(pst != NULL);
SeqList_ElemType* temp = (SeqList_ElemType*)realloc(pst->base,
sizeof(SeqList_ElemType) * (pst->capacity + SEQLIST_INC_SIZE));
if (temp == NULL)
{
printf("申请失败,内存不足\n");
return false;
}
pst->base = temp;
pst->capacity = pst->capacity + SEQLIST_INC_SIZE;
printf("扩容完毕\n");
return true;
}
//函数定义
void SeqListInit(SeqList* pst)
{
assert(pst != NULL);
pst->base = (SeqList_ElemType*)malloc( sizeof(SeqList_ElemType)*
SEQLIST_DEFAULT_SIZE);
assert(pst->base != NULL);
pst->capacity = SEQLIST_DEFAULT_SIZE;
pst->size = 0;
}
//按值查找
int SeqListFind(SeqList* pst, SeqList_ElemType key)
{
assert(pst != NULL);
for (SeqList_ElemType i = 0; i < pst->size; ++i)
{
if (key == pst->base[i])
return i;
}
return -1;
}
//尾插
void SeqListPushBack(SeqList* pst, SeqList_ElemType x)
{
assert(pst != NULL);
if( _SeqListIsFull(pst) )
{
printf("顺序表已满请扩容(请输入-1退出)\n");
return;
}
if (_SeqListIsFull(pst) && !_SeqListInc(pst))
{
printf("顺序表已满不能尾插\n");
return;
}
pst->base[pst->size++] = x;
}
//头插
void SeqListPushFront(SeqList* pst, SeqList_ElemType x)
{
assert(pst != NULL);
if (_SeqListIsFull(pst))
{
printf("顺序表已满请扩容(请输入-1退出)\n");
return;
}
if (_SeqListIsFull(pst) && !_SeqListInc(pst))
{
printf("顺序表已满不能头插\n");
return;
}
for (SeqList_ElemType i = pst->size; i > 0; --i)
{
pst->base[i] = pst->base[i-1];
}
pst->base[0] = x;
pst->size++;
}
//按位置插入
void SeqListInsertByPos(SeqList* pst, int pos, SeqList_ElemType x)
{
assert(pst != NULL);
if (_SeqListIsFull(pst) && !_SeqListInc(pst))
{
printf("顺序表已满不能插入\n");
return;
}
if (pos<=0 || pos > pst->size)
{
printf("插入位置不合法\n");
return;
}
for (SeqList_ElemType i = pst->size; i >= pos; --i)
{
pst->base[i] = pst->base[i-1];
}
pst->base[pos-1] = x;
pst->size++;
}
//根据值的大小插入
void SeqListInsertByVal(SeqList* pst, SeqList_ElemType x)
{
assert(pst != NULL);
if (_SeqListIsFull(pst) && !_SeqListInc(pst))
{
printf("顺序表已满不能插入\n");
return;
}
SeqList_ElemType i;
for ( i = 0; i < pst->size; ++i)
{
if (x < pst->base[i])
break;
}
for (SeqList_ElemType j = pst->size; j>i; --j)
{
pst->base[j] = pst->base[j-1];
}
pst->base[i] = x;
pst->size++;
}
//尾删
void SeqListPopBack(SeqList* pst)
{
assert(pst != NULL);
if (_SeqListIsEmpty(pst))
{
printf("顺序表已空不能尾删");
return;
}
pst->size--;
}
//头部删除
void SeqListPopFront(SeqList* pst)
{
assert(pst != NULL);
if (_SeqListIsEmpty(pst))
{
printf("顺序表已空不能头部删除");
return;
}
for (SeqList_ElemType i = 0; i < pst->size-1; ++i)
{
pst->base[i] = pst->base[i+ 1];
}
pst->size--;
}
//按值删除
void SeqListDeleteByVal(SeqList* pst, SeqList_ElemType key)
{
assert(pst != NULL);
if (_SeqListIsEmpty(pst))
{
printf("顺序表已空不能删除");
return;
}
if (SeqListFind(pst, key) == -1)
{
printf("顺序表中没有该值\n");
return;
}
for (SeqList_ElemType i = SeqListFind(pst, key); i< pst->size-1; ++i)
{
pst->base[i] = pst->base[i + 1];
}
pst->size--;
}
//根据位置删除
void SeqListDeleteByPos(SeqList* pst, int pos)
{
assert(pst != NULL);
if (_SeqListIsEmpty(pst))
{
printf("顺序表已空不能删除");
return;
}
if (pos<=0 || pos>pst->size)
{
printf("删除位置不合法\n");
return;
}
for (int i = pos; i <= pst->size; ++i)
{
pst->base[i-1] = pst->base[i];
}
pst->size--;
}
void SeqListClear(SeqList* pst)
{
assert(pst != NULL);
pst->size = 0;
}
//转置
void SeqListReverse(SeqList* pst)
{
assert(pst != NULL);
SeqList_ElemType begin = 0;
SeqList_ElemType end = pst->size-1;
SeqList_ElemType temp = 0;
while (begin < end)
{
temp=pst->base[end];
pst->base[end] = pst->base[begin];
pst->base[begin] = temp;
begin++;
end--;
}
}
//排序 这里用的冒泡排序
void SeqListSort(SeqList* pst)
{
assert(pst != NULL);
SeqList_ElemType temp = 0;
SeqList_ElemType count = 0;//标记已提升效率,尚未实现
for (SeqList_ElemType i = 0; i < pst->size - 1; ++i)
{
for (SeqList_ElemType j = 0; j < pst->size - 1-i; ++j)
{
if (pst->base[j] > pst->base[j+1])
{
temp = pst->base[j];
pst->base[j] = pst->base[j+1];
pst->base[j+1] = temp;
}
}
}
}
int SeqListLength(SeqList* pst)
{
assert(pst != NULL);
return pst->size;
}
int SeqListCapacity(SeqList* pst)
{
assert(pst != NULL);
return pst->capacity;
}
void SeqListShow(SeqList* pst)
{
assert(pst != NULL);
SeqList_ElemType i = 0;
for (i = 0; i < pst->size ; ++i)
{
printf("%d ", pst->base[i]);
}
printf("\n");
}
void SeqListDestroy(SeqList* pst)
{
assert(pst != NULL);
if (pst->base != NULL)
{
free(pst->base);
pst->capacity = pst->size = 0;
}
}
3.主函数(我们的顺序表及它的各个功能调用)。
#include"seqlist.h"
int main()
{
SeqList mylist;
SeqListInit(&mylist);
int Select = 0;
int key = 0;
int pos = 0;
int x = 0;
while (1)
{
printf("**************************************\n");
printf("*[1] PushBack [2] PushFront *\n");
printf("*[3] ShowList [4] _SeqListInc *\n");
printf("*[5] PopBack [6] PopFront *\n");
printf("*[7] Insert_Pos [8] Insert_Val *\n");
printf("*[9] Delate_Pos [10] Delate_Val *\n");
printf("*[11] Find [12] Reverse *\n");
printf("*[13] Sort [14] Length *\n");
printf("*[15] Capacity [16] Clear *\n");
printf("**********[0] Quit System*************\n\n");
printf("请选择\n");
scanf_s("%d", &Select);
if (Select == 0)
{
printf("已经退出\n");
return 0;
}
switch (Select)
{
case 1:
printf("请输入要尾插数据(以-1结束)\n");
while (scanf_s("%d", &x), x != -1)
{
SeqListPushBack(&mylist, x);
}
break;
case 2:
printf("请输入要头插数据(以-1结束)\n");
while (scanf_s("%d", &x), x != -1 )
{
SeqListPushFront(&mylist, x);
}
break;
case 3:
SeqListShow(&mylist);
break;
case 4:
_SeqListInc(&mylist);
break;
case 5:
SeqListPopBack(&mylist);
break;
case 6:
SeqListPopFront(&mylist);
break;
case 7:
printf("请输入要插入的位置\n");
scanf_s("%d", &pos);
printf("你想插入的值\n");
scanf_s("%d", &x);
SeqListInsertByPos(&mylist, pos, x);
break;
case 8:
printf("你想插入的值\n");
scanf_s("%d", &x);
SeqListInsertByVal(&mylist, x);
break;
case 9:
printf("你想删除的位置\n");
scanf_s("%d", &pos);
SeqListDeleteByPos(&mylist, pos);
break;
case 10:
printf("你想删除的值\n");
scanf_s("%d", &x);
SeqListDeleteByVal(&mylist, x);
break;
case 11:
printf("请输入你想寻找的值\n");
scanf_s("%d", &x);
pos=SeqListFind(&mylist, x);
printf("你想寻找的值在顺序表中的位置是%d\n", pos+1);
break;
case 12:
SeqListReverse(&mylist);
printf("逆置完毕\n");
break;
case 13:
printf("由小到大进行排序\n");
SeqListSort(&mylist);
break;
case 14:
x=SeqListLength(&mylist);
printf("顺序表的长度为%d\n",x);
break;
case 15:
x=SeqListCapacity(&mylist);
printf("顺序表的容量为%d\n", x);
break;
case 16:
SeqListClear(&mylist);
printf("已经清除顺序表\n");
break;
default:
break;
}
}
SeqListDestroy(&mylist);
}
感谢大家观看!!!