静态顺序表
定义一张顺序表也就是在内存中开辟一段连续的存储空间,并给它一个名字进行标识。只有定义了一个顺序表,才能利用该顺序表存放数据元素,也才能对该顺序表进行各种操作。
有两种定义顺序表的方法:一是静态地定义一张顺序表;二是动态地生成一张顺序表。
静态地定义一张顺序表的方法与定义一个数组的方法类似。可以描述如下:
#define MAX_SIZE 100
typedef int DataType;
typedef struct SeqList
{
DataType array[MAX_SIZE];
size_t size;
}SeqList;
静态顺序表的一些与运算实现如下:
SeqList.h
#pragma once
#define _SEQ_LIST_
#ifdef _SEQ_LIST_
#include <stdio.h>
#include <string.h>//memset
#include <assert.h>//assert
#define MAX_SIZE 100
typedef int DataType;
typedef struct SeqList
{
DataType array[MAX_SIZE];
size_t size;
}SeqList;
typedef enum TAG
{
TURE,//找到对应元素
FALSE,//未找到对应元素
}TAG;
TAG tag;
typedef struct FindRet
{
TAG IsFind;//反应是否找到对应的元素
size_t index;//找到的元素的下标
}FindRet;
FindRet ret;
void InitSeqList(SeqList* pSeq);//初始化
void PrintSeqList(SeqList* pSeq);//显示数据
void ExplandCapicity(SeqList *pSeq);//扩大容量
void PushBack(SeqList* pSeq, DataType x);//从尾插入数据
void PopBack(SeqList* pSeq);//从尾删除数据
void PushFront(SeqList* pSeq, DataType x);//从头插入数据
void PopFront(SeqList* pSeq);//从头删除数据
void Insert(SeqList* pSeq, size_t index, DataType x);//在下标为index处插入数据
void Modified(SeqList* pSeq, size_t index, DataType x);//修改下标为index的数据为x
void Removed(SeqList* pSeq, size_t index);//删除下标为index的数据
FindRet Find(SeqList *pSeq, DataType x, size_t index);//查找数据
TAG Erase(SeqList *pSeq, DataType x, TAG all);//all=FALSE时删除第一个出现的数据
//all=TURE时删除一个所有相同的数据
#endif
SeqList.c
#include "seqlist.h"
void InitSeqList(SeqList *pSeq)//初始化
{
assert(pSeq);
memset(pSeq->array, 0,MAX_SIZE*sizeof(DataType));
pSeq->size = 0;
}
void PrintSeqList(SeqList* pSeq)//显示数据
{
size_t i = 0;
assert(pSeq);
for (i = 0; i < pSeq->size; i++)
{
printf("%d ", pSeq->array[i]);
}
}
void PushBack(SeqList* pSeq, DataType x)//从尾插入数据
{
assert(pSeq);
if (pSeq->size > MAX_SIZE-1)
{
printf("The seqlist is Full\n");
return;
}
pSeq->array[pSeq->size++] = x;
}
void PopBack(SeqList* pSeq)//从尾删除数据
{
assert(pSeq);
if (pSeq->size < 1)
{
printf("The seqlist is empty\n");
return;
}
--pSeq->size;
//或者pSeq->array[--pSeq->size] = 0;
}
void PushFront(SeqList* pSeq, DataType x)//从头插入数据
{
int i = pSeq->size-1;
assert(pSeq);
if (pSeq->size > MAX_SIZE-1)
{
printf("The seqlist is Full\n");
return;
}
for (; i >= 0; i--)
{
pSeq->array[i+1] = pSeq->array[i];
}
pSeq->array[0] = x;
pSeq->size++;
}
void PopFront(SeqList* pSeq)//从头删除数据
{
size_t i = 0;
assert(pSeq);
if (pSeq->size < 1)
{
printf("The seqlist is empty\n");
return;
}
for (i = 0; i < pSeq->size - 1; i++)
{
pSeq->array[i] = pSeq->array[i + 1];
}
pSeq->size--;
}
void Insert(SeqList* pSeq, size_t index, DataType x)//在index处随机插入数据
{
size_t i = pSeq->size;
assert(pSeq);
if (index > MAX_SIZE-1)
{
printf("The seqlist is Full\n");
return;
}
for (; i > index; i--)
{
pSeq->array[i] = pSeq->array[i-1];
}
pSeq->array[index] = x;
pSeq->size++;
}
void Modified(SeqList* pSeq, size_t index, DataType x)//随机修改数据(修改index处的值)
{
assert(pSeq);
assert(index<pSeq->size);
pSeq->array[index] = x;
}
void Removed(SeqList* pSeq, size_t index)//随机删除数据
{
size_t i = index;
assert(pSeq);
assert(index<pSeq->size);
for (; i < pSeq->size - 1; i++)
{
pSeq->array[i] = pSeq->array[i + 1];
}
pSeq->size--;
}
FindRet Find(SeqList *pSeq, DataType x,size_t index)//增加了形参index,可以记录每次查找的
{ //位置,提高了效率
assert(pSeq);
ret.IsFind = FALSE;
for (; index < pSeq->size; index++)
{
if (pSeq->array[index] == x)
{
ret.index = index;
ret.IsFind = TURE;
return ret;
}
}
return ret;
}
TAG Erase(SeqList *pSeq, DataType x,TAG all)//all=FALSE表示删除一个第一次出现的数据
{ //all=TRUE表示删除一个重复的数据
assert(pSeq);
TAG success = FALSE;
ret = Find(pSeq,x,0);
while (ret.IsFind == TURE)
{
success = TURE;
Removed(pSeq,ret.index);
if (all == TURE)//表示删除一个数据
{
break;
}
ret = Find(pSeq,x,ret.index);
}
return success;
}
void Test()
{
SeqList s;
InitSeqList(&s);
printf("The PushBack is:\n");
PushBack(&s, 3);
PushBack(&s ,5);
PushBack(&s, 4);
PushBack(&s, 3);
PushBack(&s, 2);
PushBack(&s, 3);
PushBack(&s, 3);
PushBack(&s, 3);
PushBack(&s, 1);
PrintSeqList(&s);
printf("\nPopBack is:\n");
PopBack(&s);
PrintSeqList(&s);
printf("\nPushFront 10,20 is:\n");
PushFront(&s,10);
PushFront(&s,20);
PrintSeqList(&s);
printf("\nPopFront 20 is:\n");
PopFront(&s);
PrintSeqList(&s);
printf("\nInsert 99 is:\n");
Insert(&s,2,99);
PrintSeqList(&s);
printf("\nModified 99 to 88 is :\n");
Modified(&s,2,88);
PrintSeqList(&s);
printf("\nremoved 88 is:\n");
Removed(&s, 2);
PrintSeqList(&s);
printf("\nFind %d index is :\n",5);
ret = Find(&s, 5,0);
if (ret.IsFind == TURE)
{
printf("%d\n",ret.index);
}
else if (ret.IsFind == FALSE)
{
printf("is not exit\n");
}
printf("Erase 3 is :\n");
Erase(&s,3,FALSE);
PrintSeqList(&s);
}
int main()
{
Test();
return 0;
}
动态地生成一张顺序表的方法可描述如下:
#define EXPLANDSIZE 2
typedef int DataType;
typedef struct SeqList
{
DataType *elem;//指向当前空间
size_t size;//当前有效数据的长度
size_t capicity;//当前容量
}SeqList;
动态顺序表的一些与运算实现如下:
SeqList.h
#pragma once
#define _SEQ_LIST_
#ifdef _SEQ_LIST_
#include <stdio.h>//size_t
#include <stdlib.h>//malloc
#include <assert.h>//assert
#include <string.h>//memcpy
#define EXPLANDSIZE 2
typedef int DataType;
typedef struct SeqList
{
DataType *elem;//指向当前空间
size_t size;//当前有效数据的长度
size_t capicity;//当前容量
}SeqList;
typedef enum TAG
{
TURE,
FALSE,
}TAG;
TAG tag;
typedef struct FindRet
{
TAG Isfind;
size_t index;
}FindRet;
FindRet ret;
void InitSeqList(SeqList* pSeq);//初始化
void PrintSeqList(SeqList* pSeq);//显示数据
void ExplandCapicity(SeqList *pSeq);//扩大容量
void PushBack(SeqList* pSeq, DataType x);//从尾插入数据
void PopBack(SeqList* pSeq);//从尾删除数据
void PushFront(SeqList* pSeq, DataType x);//从头插入数据
void PopFront(SeqList* pSeq);//从头删除数据
void Insert(SeqList* pSeq, size_t index, DataType x);//在下标为index处插入数据
void Modified(SeqList* pSeq, size_t index, DataType x);//修改下标为index的数据为x
void Removed(SeqList* pSeq, size_t index);//删除下标为index的数据
FindRet Find(SeqList *pSeq, DataType x,size_t index);//查找数据
TAG Erase(SeqList *pSeq, DataType x,TAG all);//all=FALSE时删除第一个出现的数据
//all=TURE时删除一个所有相同的数据
void BubbleSort(SeqList *pSeq);//冒泡排序
void SeleSort(SeqList *pSeq);//选择排序
void swap(DataType *left,DataType *right);//交换值
FindRet BinarySearch(SeqList *pSeq, DataType X);//二分查找
#endif
SeqList.c
#include "seqListdongtai.h"
void InitSeqList(SeqList* pSeq)//初始化
{
assert(pSeq);
pSeq->elem = (DataType *)malloc(EXPLANDSIZE * sizeof(DataType));
pSeq->capicity = EXPLANDSIZE;
pSeq->size = 0;//表示有效数据
}
void ExplandCapicity(SeqList *pSeq)
{
if (pSeq->size == pSeq->capicity)
{
//pSeq->capicity += ExplandSize;
//DataType *newbase = (DataType *)malloc(pSeq->capicity * sizeof(DataType));
DataType *newbase = (DataType *)malloc(pSeq->capicity*2 * sizeof(DataType));
pSeq->capicity *= 2;
memcpy(newbase, pSeq->elem, pSeq->size * sizeof(DataType));
free(pSeq->elem);
pSeq->elem = newbase;
}
}
FindRet Find(SeqList *pSeq, DataType x, size_t index)//查找数据
{
assert(pSeq);
assert(index<pSeq->size);
ret.Isfind = FALSE;
for (; index < pSeq->size; index++)
{
if (pSeq->elem[index] == x)
{
ret.index = index;
ret.Isfind = TURE;
return ret;
}
}
return ret;
}
void PrintSeqList(SeqList* pSeq)//显示数据
{
assert(pSeq);
size_t i = 0;
for (; i < pSeq->size; i++)
{
printf("%d ",pSeq->elem[i]);
}
}
void PushBack(SeqList* pSeq, DataType x)//从尾插入数据
{
assert(pSeq);
ExplandCapicity(pSeq);
pSeq->elem[pSeq->size++] = x;
}
void PopBack(SeqList* pSeq)//从尾删除数据
{
assert(pSeq);
if (pSeq->size > 0)
{
pSeq->size--;
}
}
void PushFront(SeqList* pSeq, DataType x)//从头插入数据
{
assert(pSeq);
size_t i = pSeq->size;
ExplandCapicity(pSeq);
for (; i > 0; i--)
{
pSeq->elem[i] = pSeq->elem[i - 1];
}
pSeq->elem[0] = x;
pSeq->size++;
}
void PopFront(SeqList* pSeq)//从头删除数据
{
assert(pSeq);
assert(pSeq->size != 0);
size_t i = 0;
for (; i < pSeq->size - 1; i++)
{
pSeq->elem[i] = pSeq->elem[i + 1];
}
pSeq->size--;
}
void Insert(SeqList* pSeq, size_t index, DataType x)//随机插入数据
{
assert(pSeq);
assert(index<pSeq->size);
size_t i = pSeq->size;
ExplandCapicity(pSeq);
for (; i > index; i--)
{
pSeq->elem[i] = pSeq->elem[i - 1];
}
pSeq->elem[index] = x;
pSeq->size++;
}
void Modified(SeqList* pSeq, size_t index, DataType x)//随机修改数据
{
assert(pSeq);
assert(index<pSeq->size);
pSeq->elem[index] = x;
}
void Removed(SeqList* pSeq, size_t index)//随机删除数据
{
assert(pSeq);
assert(index<pSeq->size);
size_t i = index;
for (; i < pSeq->size-1; i++)
{
pSeq->elem[i] = pSeq->elem[i + 1];
}
pSeq->size--;
}
TAG Erase(SeqList *pSeq, DataType x, TAG all)//删除一个所有相同的数据
{
assert(pSeq);
tag = FALSE;
ret = Find(pSeq,5,0);
while (ret.Isfind == TURE)
{
tag = TURE;
Removed(pSeq,ret.index);
if (all == FALSE)
{
break;
}
ret = Find(pSeq,5,ret.index);
}
return tag;
}
void swap(DataType *left, DataType *right)//交换值
{
DataType tmp = *left;
*left = *right;
*right = tmp;
}
void BubbleSort(SeqList *pSeq)//冒泡排序
{
int flag = 0,count = 0;
size_t index = 0,end = 0;
assert(pSeq);
for (index = 0; index < pSeq->size - 1; index++)//循环比较
{
for (end = 0; end < (pSeq->size - 1) - index; end++)
{
count++;
if (pSeq->elem[end] > pSeq->elem[end + 1])
{
int tmp = pSeq->elem[end];
pSeq->elem[end] = pSeq->elem[end + 1];
pSeq->elem[end + 1] = tmp;
flag = 1;
}
}
if (flag == 0)
{
break;
}
flag = 0;
}
printf("冒泡次数:%d\n", count);
}
void SeleSort(SeqList *pSeq)//选择排序
{
size_t index,minindex = 0;
size_t begin = 0;
for (begin = 0; begin < pSeq->size - 1;begin++)
{
minindex = begin;
for (index = begin+1; index < pSeq->size; index++)
{
if (pSeq->elem[index] < pSeq->elem[minindex])
{
minindex = index;
}
}
if (minindex != index)
{
swap(pSeq->elem + minindex, pSeq->elem + begin);
}
}
}
FindRet BinarySearch(SeqList *pSeq, DataType x)//二分查找
{
assert(pSeq);
int left, right, mid;
left = 0;
right = pSeq->size - 1;
ret.Isfind = FALSE;
while (left <= right)
{
mid = left +((right-left) / 2);
if (pSeq->elem[mid] == x)
{
ret.Isfind = TURE;
ret.index = mid;
return ret;
}
else if (pSeq->elem[mid] < x)
{
left = mid + 1;
}
else
{
right = mid - 1;
}
}
return ret;
}
int main()
{
SeqList s;
InitSeqList(&s);//初始化
printf("PushBack is\n");
PushBack(&s, 6);//从尾插入数据
PushBack(&s, 5);
PushBack(&s, 4);
PushBack(&s, 5);
PushBack(&s, 5);
PushBack(&s, 3);
PushBack(&s, 5);
PushBack(&s, 2);
PushBack(&s, 1);
PrintSeqList(&s);
printf("\nPopBack 1 is :\n");
PopBack(&s);//从尾删除数据
PrintSeqList(&s);
printf("\nPushFront 99 is:\n");
PushFront(&s,99);//从前插入数据
PrintSeqList(&s);
printf("\nPopFront 99 is:\n");
PopFront(&s);//从前删除数据
PrintSeqList(&s);
printf("\nInsert 88 is:\n");
Insert(&s,1,88);//在下标为1的地方插入数据
PrintSeqList(&s);
printf("\nModified 5 is :\n");
Modified(&s,2,55);//修改下标为2的的数据为55
PrintSeqList(&s);
printf("\nRemove 4 is:\n");
Removed(&s,3);//删除下标为3的数据
PrintSeqList(&s);
printf("\nErase 5 is:\n");
Erase(&s,5,TURE);//删除所有5
PrintSeqList(&s);
printf("\nBubbleSort:\n");
BubbleSort(&s);//冒泡排序
PrintSeqList(&s);
printf("\n");
BubbleSort(&s);//再次冒泡排序
PrintSeqList(&s);
printf("\nSeleSort:\n");
SeleSort(&s);//选择排序
PrintSeqList(&s);
printf("\nBinarySearch 88 is :\n");
BinarySearch(&s, 88);//二分查找
if (ret.Isfind == TURE)
{
printf("下标为:%d\n",ret.index);
}
else
{
printf("Search is failed\n");
}
return 0;
}
线性表优点是:
无须为表示表中元素之间的逻辑关系增加额外的存储空间;
可以方便地随机访问表中任一位置的元素。
缺点是:
插入和删除运算不方便,除表尾的位置外,在表的其他位置上进行插入或删除操作都必须移动大量元素,其效率较低;
由于数组要求占用连续的存储空间,存储分配只能预先进行静态分配。因此,当表长变化较大时,难以确定数组的合适的大小。确定大了将造成浪费。
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-12-27 23:57:17