头文件里:
#define _CRT_SECURE_NO_WARNINGS 1
#ifndef __SEQLIST_H__
#define __SEQLIST_H__
#define MAX 100
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
typedef int DataType; //类型重命名
typedef struct Seqlist
{
DataType data[MAX];
int sz;
}Seqlist,*pSeqlist;
void printSeqlist(pSeqlist pSeq); //显示当顺序表所有数据
void InitSeqlist(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 Remove(pSeqlist pSeq, DataType x); //删除指定的一个元素
void RemoveAll(pSeqlist pSeq, DataType x); //删除所有顺序表里出现的某个元素
void sort(pSeqlist pSeq); //排序
int BinarySeach(pSeqlist pSeq, DataType x); //二分查找指定元素,返回位置
void memu(); //打印菜单
#endif
函数实现
#include"Seqlist.h"
void memu()
{
printf("**********静态顺序表*********\n");
printf("***1. 指定位置插入指定数据***\n");
printf("***2. 删除指定数据 ***\n");
printf("***3. 删除指定的所有数据 ****\n");
printf("*****4.头插 5.头删*****\n");
printf("*****6.尾插 7.尾删*****\n");
printf("*****8.排序 9.查找*****\n");
printf("*****10.打印数据 0.退出*****\n");
}
void printSeqlist(pSeqlist pSeq)
{
int i = 0;
assert(pSeq);
for (i = 0; i < pSeq->sz; i++)
{
printf("%d ", pSeq->data[i]);
}
printf("\n");
}
void InitSeqlist(pSeqlist pSeq)
{
assert(pSeq);
memset(pSeq->data, 0, sizeof(DataType)*MAX);
pSeq->sz = 0;
}
void PushBack(pSeqlist pSeq, DataType x)
{
assert(pSeq);
if (pSeq->sz == MAX)
{
printf("已满,无法插入!\n");
return;
}
pSeq->data[pSeq->sz] = x;
pSeq->sz++;
printf("成功插入!\n");
}
void PopBack(pSeqlist pSeq)
{
assert(pSeq);
if (pSeq->sz == 0)
{
printf("没有可删的数据!\n");
return;
}
pSeq->sz--;
printf("尾删成功!\n");
}
void PushFront(pSeqlist pSeq, DataType x)
{
int i = 0;
assert(pSeq);
for (i = (pSeq->sz) - 1; i >= 0; i--)
{
pSeq->data[i + 1] = pSeq->data[i];
}
pSeq->data[0] = x;
pSeq->sz++;
printf("头插成功!\n");
}
void PopFront(pSeqlist pSeq)
{
int i = 0;
assert(pSeq);
if (pSeq->sz == 0)
{
printf("无数据可删!\n");
return;
}
for (i = 0; i < pSeq->sz-1; i++)
{
pSeq->data[i] = pSeq->data[i +1];
}
pSeq->sz--;
printf("头删成功!\n");
}
void Insert(pSeqlist pSeq, int pos, DataType x)
{
int i = 0;
assert(pSeq);
if ( pos<1 )
{
printf("插入位置不合法\n");
}
for (i = (pSeq->sz)-1; i >=pos-1; i--)
{
pSeq->data[i + 1] = pSeq->data[i];
}
pSeq->data[pos - 1] = x;
pSeq->sz++;
printf("插入成功!\n");
}
void Remove(pSeqlist pSeq, DataType x)
{
int i = 0;
int j = 0;
assert(pSeq);
if (pSeq->sz == 0)
{
printf("无数据可删!\n");
return;
}
for (i = 0; i < pSeq->sz; i++)
{
if (pSeq->data[i] == x)
{
for (j = i; j < pSeq->sz; j++)
{
pSeq->data[j] = pSeq->data[j + 1];
}
pSeq->sz--;
printf("删除成功!\n");
}
}
if (j==0)
{
printf("无该数据!\n");
return;
}
}
void RemoveAll(pSeqlist pSeq, DataType x)
{
int i = 0;
int j = 0;
int count = 0;
assert(pSeq);
if (pSeq->sz == 0)
{
printf("无数据可删!\n");
return;
}
while( i < pSeq->sz)
{
if (pSeq->data[i] == x)
{
for (j = i; j < pSeq->sz; j++)
{
pSeq->data[j] = pSeq->data[j + 1];
}
pSeq->sz--;
}
else
i++;
}
if (j == 0)
{
printf("无该数据!\n");
return;
}
printf("删除成功!\n");
}
void sort(pSeqlist pSeq)
{
assert(pSeq);
int i = 0;
int j = 0;
for (i = 0; i < pSeq->sz - 1; i++)
{
for (j = 0; j < pSeq->sz - 1 - i; j++)
{
if (pSeq->data[j]>pSeq->data[j + 1])
{
DataType temp = pSeq->data[j];
pSeq->data[j] = pSeq->data[j + 1];
pSeq->data[j + 1] = temp;
}
}
}
}
int BinarySeach(pSeqlist pSeq, DataType x)
{
int mid = 0;
int left = 0;
int right = (pSeq->sz) - 1;
assert(pSeq);
if (pSeq->sz == 0)
{
printf("当前无数据!\n");
return 0;
}
sort(pSeq); //二分查找前先对数据进行排序。
while (left <= right)
{
mid = (left + right) / 2;
if (x > pSeq->data[mid])
{
left = mid+1;
}
else if (x < pSeq->data[mid])
{
right = mid-1;
}
else
{
return mid;
}
}
return -1;
}
主函数
#include"Seqlist.h"
int main()
{
Seqlist Seq;
int num = 0;
int pos = 0;
int x = 0;
memu();
InitSeqlist(&Seq);
while (1)
{
printf("请输入你要执行的操作:\n");
scanf("%d", &num);
switch (num)
{
case 1:
printf("请输入要插入的位置:\n");
scanf("%d", &pos);
printf("请输入要插入的元素:\n");
scanf("%d", &x);
Insert(&Seq, pos, x);
break;
case 2:
printf("请输入要删除的元素:\n");
scanf("%d", &x);
Remove(&Seq, x);
break;
case 3:
printf("请输入要删除的元素:\n");
scanf("%d", &x);
RemoveAll(&Seq, x);
break;
case 4:
printf("请输入要头插的元素:\n");
scanf("%d", &x);
PushFront(&Seq, x);
break;
case 5:
break;
case 6:
printf("请输入要尾插的元素:\n");
scanf("%d", &x);
PushBack(&Seq, x);
break;
case 7:
PopBack(&Seq);
break;
case 8:
sort(&Seq);
printSeqlist(&Seq);
break;
case 9:
printf("请输入要查找的元素:\n");
scanf("%d", &x);
int ret=BinarySeach(&Seq, x);
if (ret == -1)
{
printf("无该数据!\n");
}
else
{
printf("查找数据的位置是:%d\n", ret+1);
}
break;
case 10:
printSeqlist(&Seq);
break;
case 0:
exit(0);
break;
default:
printf("命令输入错误!\n");
break;
}
}
getchar();
return 0;
}
实现静态顺序表的时候,我们应该首先考虑到异常情况并给出处理的办法,不应该仅仅满足于将函数的功能实现。测试的时候也要注意多测试几种不同的情况,尽量保证程序在各种情况下都能正常运行。比如在实现二分查找函数的时候,刚开始在下标为中间的元素与要查找的数据不相等的情况下直接将中间位置赋给了左边或者右边,测试的时候发现,在查找最后一个元素的时候总会陷入死循环,所以我改成了现在的样子,再测试了好几组都没有问题。
为了使得程序更加安全,我们在每一个功能函数里都加入assert检验传入的指针。静态顺序表的实现虽然不是很困难,但是依然要注意一定要将程序写的相对完整,这是我在实现静态顺序表的感悟。