在了解线性结构后我们知道它可分为顺序表和链表两种,而顺序表又分为静态顺序表和动态顺序表.
静态顺序表和静态通讯录的实现极为相似,但是我们知道静态版本有着明显的缺陷,空间分配太大易造成浪费,太小又不便存储,而动态版本正好可以解决这个问题。
既然前面提到线性结构的组成,那么我们就在说说链表分为哪些:它可分为单向链表,双向链表,循环链表和双向循环链表,这些我们后期再讨论这些。好了,该回到今天的主题上来了——动态顺序表的实现!
首先,动态顺序表的功能在头文件中已经全部列出来了,在排序的时候给出了三种方式:冒泡排序,直接插入排序和选择排序。在实现测试函数的时候记得打印菜单中的顺序需要和case语句中的顺序保持一致哦,我在这就栽过跟头。。。还值得注意的是:在我们的测试函数中,应当创建一个结构体变量,然后调用函数的时候把其地址传进去,否则传值的话会有压栈的开销,这样一来时间和空间就都浪费很大了。
下来我们就用代码实现它:
Seqlist.h
#define _CRT_SECURE_NO_WARNINGS 1
#ifndef _SEQLIST_D_H_
#define _SEQLIST_D_H_
#include
#include
#include
#define DEFAULT_SZ 2
#define INC_SZ 2
typedef int DataType;
typedef struct Seqlist
{
DataType *data;
int sz; //实际容量大小
int capacity;
}Seqlist,*pSeqlist;
void PrintSeqlist(pSeqlist pSeq); //顺序表打印输出
void InitSeqlist(pSeqlist pSeq); //进行初始化
void DestroySeqlist(pSeqlist pSeq);
void PushBack(pSeqlist pSeq,DataType x);//在顺序表尾部插入元素
void PopBack(pSeqlist pSeq); //在顺序表尾部删除元素
void PushFront(pSeqlist pSeq,DataType x);//在顺序表头部插入元素
void PopFront(pSeqlist pSeq); //在顺序表头部删除元素
void Insert(pSeqlist pSeq,int pos,DataType x);//在顺序表指定位置插入元素
void Erase(pSeqlist pSeq,DataType pos); //在指定位置删除该元素
void Remove(pSeqlist pSeq,DataType x); //删除指定元素
void RemoveAll(pSeqlist pSeq,DataType x); //删除所有指定的元素
void BubbleSort(pSeqlist pSeq); //冒泡排序
void InsertionSort(pSeqlist pSeq); //直接插入排序
void SelectSort(pSeqlist pSeq); //选择排序
int BinarySearch(pSeqlist pSeq,DataType x); //二分查找
#endif
Seqlist.c
#include"Seqlist.h"
void PrintSeqlist(pSeqlist pSeq) //顺序表打印输出
{
int i=0;
for(i=0;isz;i++)
{
printf("%d\n",pSeq->data[i]);
}
}
void InitSeqlist(pSeqlist pSeq) //进行初始化
{
pSeq->data=(DataType *)malloc(DEFAULT_SZ*sizeof(DataType));
if(pSeq->data==NULL)
{
printf("out of memory");
exit(EXIT_FAILURE);
}
pSeq->sz=0;
pSeq->capacity=0;
memset(pSeq->data,0,DEFAULT_SZ*sizeof(DataType));
}
void DestroySeqlist(pSeqlist pSeq)
{
free(pSeq->data);
pSeq->data=NULL;
pSeq->capacity=0;
pSeq->sz=0;
}
void Check_capacity(pSeqlist pSeq)
{
DataType *tmp=NULL;
if(pSeq->sz==pSeq->capacity)
{
tmp=(DataType *)realloc(pSeq->data,(pSeq->capacity+=INC_SZ)*sizeof(DataType));
if(tmp==NULL)
{
printf("out of memmory!");
exit(EXIT_FAILURE);
}
pSeq->data=tmp;
pSeq->capacity+=INC_SZ;
}
}
void PushBack(pSeqlist pSeq,DataType x) //在顺序表尾部插入元素
{
Check_capacity(pSeq);
pSeq->data[pSeq->sz]=x;
pSeq->sz++;
}
void PopBack(pSeqlist pSeq) //在顺序表尾部删除元素
{
if(pSeq->sz==0)
{
printf("顺序表已空!");
return;
}
pSeq->sz--;
}
void PushFront(pSeqlist pSeq,DataType x) //在顺序表头部插入元素
{
int i=0;
Check_capacity(pSeq);
for(i=pSeq->sz-1;i>=0;i--)
{
pSeq->data[i+1]=pSeq->data[i];
}
pSeq->data[0]=x;
pSeq->sz++;
}
void PopFront(pSeqlist pSeq) //在顺序表头部删除元素
{
int i=0;
if(pSeq->sz==0)
{
printf("顺序表已空!");
return;
}
for(i=0;isz;i++)
{
pSeq->data[i]=pSeq->data[i+1];
}
pSeq->sz--;
}
void Insert(pSeqlist pSeq,int pos,DataType x) //在顺序表指定位置插入元素
{
int i=0;
Check_capacity(pSeq);
for(i=pSeq->sz-1;i>=pos;i--)
{
pSeq->data[i+1]=pSeq->data[i];
}
pSeq->data[pos]=x;
pSeq->sz++;
}
void Erase(pSeqlist pSeq,DataType pos) //在顺序表指定位置删除元素
{
int i=0;
if((pos<0)&&(pos>pSeq->sz))
{
printf("删除位置不合法!");
return;
}
for(i=pos;isz-1;i++)
{
pSeq->data[i]=pSeq->data[i+1];
}
pSeq->sz--;
}
void Remove(pSeqlist pSeq,DataType x) //删除指定元素
{
int i=0;
int ret=0;
ret=BinarySearch(pSeq,x);
if(ret==-1)
{
printf("没有找到该元素!\n");
return;
}
for(i=ret;isz;i++)
{
pSeq->data[i]=pSeq->data[i+1];
}
pSeq->sz--;
}
void RemoveAll(pSeqlist pSeq,DataType x) //删除所有指定的元素
{
int i=0;
int ret=0;
ret=BinarySearch(pSeq,x);
while(retsz)
{
if(ret==-1)
{
printf("没有找到该元素!\n");
return;
}
for(i=ret;isz;i++)
{
pSeq->data[i]=pSeq->data[i+1];
}
pSeq->sz--;
ret++;
}
}
void BubbleSort(pSeqlist pSeq) //冒泡排序
{
int i=0;
int j=0;
int m=0;
DataType tmp=0;
int k=pSeq->sz-1;
int flag=0; //表示有序
for(i=0;isz-1;i++)
{
m=0;
flag=0;
for(j=0;jdata[j])>(pSeq->data[j+1]))
{
tmp=pSeq->data[j];
pSeq->data[j]=pSeq->data[j+1];
pSeq->data[j+1]=tmp;
flag=1;
m=j; //记住最后一次交换的位置
}
}
if(flag==0)
{
return;
}
m=k; //将k设置为最后一次交换的位置
}
}
void InsertionSort(pSeqlist pSeq) //直接插入排序
{
int i=0;
int j=0;
DataType tmp=0;
for(i=1;isz;i++) //控制插入的位置(假设第一个为有序)
{
tmp=pSeq->data[i];
for(j=i-1;(j>=0)&&(pSeq->data[j]>tmp);j--)//满足取出的值大于这个值才进入循环
{
pSeq->data[j+1]=pSeq->data[j];
}
pSeq->data[j+1]=tmp;
}
}
void SelectSort(pSeqlist pSeq) //选择排序
{
int i=0;
int j=0;
DataType tmp=0;
int min=0; //作为最小值的下标
for(i=0;isz;i++)
{
min=i; //假设第一个为有序(对升序而言第一个为最小值)
for(j=i+1;jsz;j++)
{
if(pSeq->data[j]data[min])
{
min=j;
}
if(min!=i)
{
tmp=pSeq->data[min];
pSeq->data[min]=pSeq->data[i];
pSeq->data[i]=tmp;
}
}
}
}
int BinarySearch(pSeqlist pSeq,DataType x) //二分查找
{
int left=0;
int right=pSeq->sz-1;
int mid=0;
mid=(right-left)/2+left;
while(leftdata[mid]data[mid]>x)
{
left=mid+1;
}
else
return mid; //返回要查找值的下标,否则要查找的可能也为-1
}
return -1;
}
test.c
#include "Seqlist.h"
void menu()
{
printf("******************************************\n");
printf("***0.exit***************1.PrintSeqlist****\n");
printf("***2.InitSeqlist********3.PushBack********\n");
printf("***4.PopBack************5.PushFront*******\n");
printf("***6.PopFront**********7.Insert***********\n");
printf("***8.Remove*************9.RemoveAll*******\n");
printf("***10.BubbleSort******11.InsertionSort****\n");
printf("***12.SelectSort*****13.BinarySearch******\n");
printf("******14.DestroySeqlist***15.Erase********\n");
printf("******************************************\n");
}
void test()
{
Seqlist Seq ; //创建一个结构体变量
DataType x=0;
int ret=0;
int pos=0;
int input=1;
pSeqlist pSeq = &Seq;
InitSeqlist(&Seq);
while(input)
{
menu();
printf("请选择:");
scanf("%d",&input);
switch(input)
{
case 0:
exit(1);
break;
case 1:
PrintSeqlist(&Seq);
break;
case 2:
InitSeqlist(&Seq);
break;
case 3:
printf("请输入一个要插入的数:");
scanf("%d",&x);
PushBack(&Seq,x);
break;
case 4:
PopBack(&Seq);
break;
case 5:
printf("请输入一个要插入的数:");
scanf("%d",&x);
PushFront(&Seq,x);
break;
case 6:
PopFront(&Seq);
break;
case 7:
printf("请输入一个要插入的数:");
scanf("%d",&x);
printf("请选择要插入的位置:");
scanf("%d",&pos);
Insert(&Seq,pos,x);
break;
case 8:
printf("请输入要删除的元素:");
scanf("%d",&x);
Remove(&Seq,x);
break;
case 9:
printf("请输入要删除的元素:");
scanf("%d",&x);
RemoveAll(&Seq,x);
break;
case 10:
BubbleSort(&Seq);
break;
case 11:
InsertionSort(&Seq);
break;
case 12:
SelectSort(&Seq);
break;
case 13:
printf("请输入要查找的数:");
scanf("%d",&x);
ret=BinarySearch(&Seq,x);
if(ret!=-1)
{
if(pSeq->data[ret]==x)
{
printf("%d\n",x);
printf("查找成功!\n");
}
else
printf("查找失败!\n");
}
if(ret==-1)
{
printf("查找失败!\n");
}
break;
case 14:
DestroySeqlist(&Seq);
break;
case 15:
printf("请输入要删除元素的位置:");
scanf("%d",x);
Erase(&Seq,x);
default:
printf("输入错误!");
break;
}
}
}
int main()
{
test();
system("pause");
return 0;
}