顺序表的静态存储:
通过数组保存数据,程序分2个源文件和一个头文件:
sxb.h包含程序需要用到的函数原型和结构声明,一般类型定义
test.c用来测试程序
sxb.c包含用到的函数实现
test.c:
/* 顺序表 */
#include <stdio.h>
#include <windows.h>
#include "sxb.h" //定义SeqList,DataType
void Menu ( void ); //菜单
void PrintSeqList ( SeqList * seq ); //打印顺序表
int main ( )
{
SeqList seqList;
SeqList * seq = &seqList;
Menu ( );
int choice = 0;
DataType x = 0;
size_t pos = 0;
scanf ( "%d", &choice );
while ( 0 != choice )
{
switch ( choice )
{
case 1: InitSeqList ( seq );
break;
case 2: DestorySeqList ( seq );
break;
case 3: if ( SeqListIsEmpty ( seq ) )
{
printf ( "顺序表为空!\n" );
}
else
{
printf ( "顺序表不为空!\n" );
}
break;
case 4: if ( SeqListIsFull ( seq ) )
{
printf ( "顺序表已满!\n" );
}
else
{
printf ( "顺序表未满!\n" );
}
break;
case 5: printf ( "请输入数据: " );
scanf ( "%d", &x );
if ( PushBack ( seq, x ) )
{
printf ( "添加成功!\n" );
}
else
{
printf ( "添加失败!\n" );
}
break;
case 6: if ( PopBack ( seq ) )
{
printf ( "删除成功!\n" );
}
else
{
printf ( "删除失败!\n" );
}
break;
case 7: printf ( "请输入数据: " );
scanf ( "%d", &x );
if ( PushFront ( seq, x ) )
{
printf ( "添加成功!\n" );
}
else
{
printf ( "添加失败!\n" );
}
break;
case 8: if ( PopFront ( seq ) )
{
printf ( "删除成功!\n" );
}
else
{
printf ( "删除失败!\n" );
}
break;
case 9: printf ( "请输入位置: " );
scanf ( "%u", &pos );
printf ( "请输入数值: " );
scanf ( "%d", &x );
int flag = Insert ( seq, pos, x );
if ( 0 == flag )
{
printf ( "添加成功!\n" );
}
else if ( -2 == flag )
{
printf ( "pos位置不合法!\n" );
}
else if ( -1 == flag )
{
printf ( "添加失败!\n" );
}
break;
case 10: printf ( "请输入要查找的元素: " );
scanf ( "%d", &x );
flag = Find ( seq, x );
if ( -2 == flag )
{
printf ( "未找到元素%d!\n", x );
}
else if ( -1 == flag )
{
printf ( "查找失败,表为空!\n" );
}
else
{
printf ( "找到元素%d,位置为%d\n", x, flag );
}
break;
case 11: printf ( "请输入位置: " );
scanf ( "%u", &pos );
if ( Erase ( seq, pos ) )
{
printf ( "删除成功!\n" );
}
else
{
printf ( "删除失败!\n" );
}
break;
case 12: printf ( "请输入要删除元素:" );
scanf ( "%d", &x );
if ( Remove ( seq, x ) )
{
printf ( "删除成功!\n" );
}
else
{
printf ( "删除失败!\n" );
}
break;
case 13: printf ( "请输入要删除元素:" );
scanf ( "%d", &x );
if ( RemoveAll ( seq, x ) )
{
printf ( "删除成功!\n" );
}
else
{
printf ( "删除失败!\n" );
}
break;
case 14: PrintSeqList ( seq );
putchar ( '\n' );
break;
case 15: if ( BubbleSort ( seq ) )
{
printf ( "排序成功!\n" );
}
else
{
printf ( "排序失败!\n" );
}
break;
case 16: printf ( "请输入要查找的元素:" );
scanf ( "%d", &x );
flag = BinarySearch ( seq, x );
if ( -1 == flag )
{
printf ( "查找失败!\n" );
}
else
{
printf ( "查找成功! " );
printf ( "元素%d出现位置为%d\n", x, flag );
}
break;
case 17: if ( SelectSort ( seq ) )
{
printf ( "排序成功!\n" );
}
else
{
printf ( "排序失败!\n" );
}
break;
//case 18: printf ( "请输入要查找的元素:" );
// scanf ( "%d", &x );
// int leftIndex = 0;
// int rightIndex = seq->size - 1;
// int midIndex = leftIndex + ( ( rightIndex - leftIndex ) >> 1 );
//
// flag = BinarySearch ( seq, x, leftIndex, rightIndex, midIndex );
// if ( -1 == flag )
// {
// printf ( "查找失败!\n" );
// }
// else
// {
// printf ( "查找成功! " );
// printf ( "元素%d出现位置为%d\n", x, flag );
// }
// break;
default: printf ( "放弃吧!\n" );
break;
}
Menu ( );
scanf ( "%d", &choice );
}
system ( "pause" );
return 0;
}
void Menu ( void ) //菜单
{
printf ( "***************************************************************\n" );
printf ( " 1.初始化 2.清空\n" );
printf ( " 3.是否为空 4.是否已满\n" );
printf ( " 5.尾添数据 6.尾删数据\n" );
printf ( " 7.头添数据 8.头删数据\n" );
printf ( " 9.指定位置添加数据 10.查找数据\n" );
printf ( " 11.删除指定位置数据 12.删除指定数据\n" );
printf ( " 13.删除所有指定数据 14.显示顺序表\n" );
printf ( " 15.由小到大排序 16.查找数据\n" );
printf ( " 17.由大到小排序\n" );
printf ( "***************************************************************\n" );
}
void PrintSeqList ( SeqList * seq ) //打印顺序表
{
int i = 0;
while ( i < seq->size )
{
printf ( "%d ", seq->array[i] );
++i;
}
putchar ( '\n' );
}
//void PrintSeqList ( SeqList * seq, int count //逆序递归打印顺序表
//{
// if ( count == seq->size - 1 )
// {
// ;
// }
// else
// {
// PrintSeqList ( seq, count + 1 );
// }
//
// printf ( "%d ", seq->array[count] );
//}
/* 顺序表类型的头文件 */
#ifndef SXB_H_
#define SXB_H_
#include <stdbool.h> //为bool类型提供支持
/* 一般类型定义 */
typedef int DataType; //抽象数据类型
/* 特定于程序的声明 */
#define MAX_SIZE 5 //最大存储元素个数
struct SeqList {
DataType array[MAX_SIZE];
size_t size; //顺序表中元素个数
};
/* 一般类型定义 */
typedef struct SeqList SeqList;
/* 函数原型 */
/* 操作: 初始化顺序表 */
/* 操作前:seq指向一个顺序表 */
/* 操作后:该顺序表被初始化为空顺序表 */
void InitSeqList ( SeqList * seq );
/* 操作: 将顺序表清空 */
/* 操作前: seq指向一个已初始化的顺序表 */
/* 操作后:该顺序表被置为空顺序表 */
void DestorySeqList ( SeqList * seq );
/* 操作: 确定顺序表是否为空 */
/* 操作前: seq指向一个已初始化的顺序表 */
/* 操作后:如果该顺序表为空则返回true;否则返回false */
bool SeqListIsEmpty ( SeqList * seq );
/* 操作: 确定顺序表是否已满 */
/* 操作前: seq指向一个已初始化的顺序表 */
/* 操作后:如果该顺序表已满则返回true;否则返回false */
bool SeqListIsFull ( SeqList * seq );
/* 操作: 在顺序表尾部添加一个数据 */
/* 操作前: x 是要被增加到顺序表中的数据 */
/* seq指向一个已初始化的顺序表 */
/* 操作后:如果可能的话,在顺序表尾部添加一个新数据, */
/* 函数返回true;否则函数返回false */
bool PushBack ( SeqList * seq, DataType x );
/* 操作: 在顺序表尾部删除一个数据 */
/* 操作前: seq指向一个已初始化的顺序表 */
/* 操作后:删除成功函数返回true, */
/* 否则函数返回false */
bool PopBack ( SeqList * seq );
/* 操作: 在顺序表头部添加一个数据 */
/* 操作前: x 是要被增加到顺序表中的数据 */
/* seq指向一个已初始化的顺序表 */
/* 操作后:如果可能的话,在顺序表头部添加一个新数据, */
/* 函数返回true;否则函数返回false */
bool PushFront ( SeqList * seq, DataType x );
/* 操作: 在顺序表头部删除一个数据 */
/* 操作前: seq指向一个已初始化的顺序表 */
/* 操作后:删除成功函数返回true, */
/* 否则函数返回false */
bool PopFront ( SeqList * seq );
/* 操作: 在顺序表指定位置添加一个数据 */
/* 操作前: x 是要被增加到顺序表中的数据 */
/* pos 是要添加到顺序表中的位置 */
/* 第几个元素即pos值为几 */
/* seq指向一个已初始化的顺序表 */
/* 操作后:如果可能的话,在顺序表pos位置添加一个新数据, */
/* 函数返回0;表已满函数返回-1;pos位置不合法返回-2 */
int Insert ( SeqList * seq, size_t pos, DataType x );
/* 操作: 在顺序表中查找某个元素 */
/* 操作前: x 是要查找的数据 */
/* seq指向一个已初始化的顺序表 */
/* 操作后:如果找到,返回那个元素的位置; */
/* 表为空返回-1;未找到返回-2 */
int Find ( SeqList * seq, DataType x );
/* 操作: 在顺序表指定位置删除一个元素 */
/* 操作前: pos 是要删除元素的位置 */
/* seq指向一个已初始化的顺序表 */
/* 操作后:删除成功返回true;失败(表为空按删除失败对待)返回false */
bool Erase ( SeqList * seq, size_t pos );
/* 操作: 在顺序表中删除指定元素一次 */
/* 操作前: x是要删除的元素 */
/* seq指向一个已初始化的顺序表 */
/* 操作后:删除成功返回true;失败(表为空按删除失败对待)返回false */
bool Remove ( SeqList * seq, DataType x );
/* 操作: 在顺序表中删除指定元素所有值 */
/* 操作前: x是要删除的元素 */
/* seq指向一个已初始化的顺序表 */
/* 操作后:删除成功返回true;失败(表为空按删除失败对待)返回false */
bool RemoveAll ( SeqList * seq, DataType x );
/* 操作: 由小到大排序顺序表 */
/* 操作前: seq指向一个已初始化的顺序表 */
/* 操作后:排序顺序表,成功返回true;失败(表为空按失败对待)返回false */
bool BubbleSort ( SeqList * seq );
/* 操作: 由大到小排序顺序表 */
/* 操作前: seq指向一个已初始化的顺序表 */
/* 操作后:排序顺序表,成功返回true;失败(表为空按失败对待)返回false */
bool SelectSort ( SeqList * seq );
/* 操作: 在顺序表中查找一个元素 */
/* 操作前: x是要查找的元素 */
/* seq指向一个已初始化的顺序表 */
/* 操作后:查找成功返回此元素出现位置;失败(表为空按查找失败对待)返回-1 */
int BinarySearch ( SeqList * seq, DataType x );
/* 操作: 在顺序表中查找一个元素 */
/* 操作前: x是要查找的元素 */
/* seq指向一个已初始化的顺序表 */
/* 操作后:查找成功返回此元素出现位置;失败(表为空按查找失败对待)返回-1 */
//int BinarySearch ( SeqList * seq, DataType x, int leftIndex, int rightIndex, int midIndex );//递归版本
#endif
sxb.c:
/* sxb.c -- 支持顺序表操作的函数 */
#include <stdio.h>
#include <string.h> //为 memset ( ) 函数提供原型
#include "sxb.h"
/* 局部函数原型 */
static bool CheckPos ( SeqList * seq, size_t pos );
static bool Swap ( DataType * val1, DataType * val2 );
/* 接口函数 */
/* 把顺序表初始化为空顺序表 */
void InitSeqList ( SeqList * seq )
{
memset ( seq, 0, ( sizeof ( DataType ) * MAX_SIZE ) );
seq->size = 0;
}
/* 把顺序表清为空表 */
void DestorySeqList ( SeqList * seq )
{
memset ( seq, 0, ( sizeof ( DataType ) * MAX_SIZE ) );
seq->size = 0;
}
/* 检查顺序表是否为空 */
bool SeqListIsEmpty ( SeqList * seq )
{
if ( 0 == seq->size )
{
return true;
}
return false;
}
/* 检查顺序表是否已满 */
bool SeqListIsFull ( SeqList * seq )
{
if ( MAX_SIZE == seq->size )
{
return true;
}
return false;
}
/* 添加一个数据到由seq指向的顺序表尾部 */
bool PushBack ( SeqList * seq, DataType x )
{
if ( SeqListIsFull ( seq ) )
{
return false; //顺序表已满
}
seq->array[seq->size] = x;
++seq->size; //顺序表保存元素数+1
return true;
}
/* 从seq指向的顺序表尾部删除一个数据 */
bool PopBack ( SeqList * seq )
{
if ( SeqListIsEmpty ( seq ) )
{
return false;
}
--seq->size; //将列表保存元素数减1
return true;
}
/* 添加一个数据到seq指向的顺序表的头部 */
bool PushFront ( SeqList * seq, DataType x )
{
if ( SeqListIsFull ( seq ) )
{
return false;
}
int i = seq->size - 1; //顺序表中最后一个元素索引
while ( i >= 0 )
{
seq->array[i + 1] = seq->array[i];
--i;
}
seq->array[0] = x;
++seq->size;
return true;
}
/* 从seq指向的顺序表头部删除一个数据 */
bool PopFront ( SeqList * seq )
{
if ( SeqListIsEmpty ( seq ) )
{
return false;
}
int i = 0; //索引用于将表中除第一个元素外每个元素前移一位
while ( i <= ( seq->size - 1 ) )
{
seq->array[i] = seq->array[i + 1];
++i;
}
--seq->size;
return true;
}
/* 在seq指向的顺序表指定位置添加一个数据 */
int Insert ( SeqList * seq, size_t pos, DataType x )
{
if ( SeqListIsFull ( seq ) )
{
return -1;
}
if ( !( CheckPos ( seq, pos ) ) ) //pos值不合法返回-2
{
return -2;
}
int i = seq->size - 1; //索引用来遍历操作顺序表,将pos位置空出
while ( i >= ( int )pos - 1 ) //why强转后才正确?
{
seq->array[i + 1] = seq->array[i];
--i;
}
seq->array[i + 1] = x;
++seq->size;
return 0;
}
/* 在seq指向的顺序表中查找元素,并返回元素第一次出现时位置 */
int Find ( SeqList * seq, DataType x )
{
if ( SeqListIsEmpty ( seq ) )
{
return -1; //表为空,返回-1
}
int i = 0; //索引遍历顺序表,查找元素
while ( i <= ( seq->size - 1 ) )
{
if ( x == seq->array[i] ) //元素被找到
{
return ( i + 1 ); //返回元素第一次被找到时位置
}
++i;
}
return -2; //未找到元素
}
/* 在seq指向的顺序表中删除位置pos处的元素 */
bool Erase ( SeqList * seq, size_t pos )
{
if ( SeqListIsEmpty ( seq ) )
{
return false;
}
if ( !( CheckPos ( seq, pos ) ) ) //pos值不合法返回false
{
return false;
}
int i = pos - 1; //索引遍历顺序表,将pos处以后元素前移一位
while ( i < ( seq->size - 1 ) )
{
seq->array[i] = seq->array[i + 1];
++i;
}
--seq->size;
return true;
}
/* 在seq指向的顺序表中删除指定元素一次 */
bool Remove ( SeqList * seq, DataType x )
{
if ( SeqListIsEmpty ( seq ) )
{
return false;
}
int index = -1; //index 用于存放 x 第一次出现位置索引(如果顺序表中存在元素x的话)
int i = 0; //索引用于遍历顺序表查找元素x
while ( i < seq->size)
{
if ( x == seq->array[i] )
{
index = i;
break;
}
++i;
}
if ( -1 == index ) //顺序表中不存在元素 x
{
return false;
}
int j = index; //索引遍历顺序表,将索引j处以后元素前移一位(覆盖删除元素 x 第一次出现位置)
while ( j < ( seq->size - 1 ) )
{
seq->array[j] = seq->array[j + 1];
++j;
}
--seq->size;
return true;
}
/* 在seq指向的顺序表中,删除指定元素所有值 */
bool RemoveAll ( SeqList * seq, DataType x )
{
if ( SeqListIsEmpty ( seq ) )
{
return false;
}
int count = 0; //计算指定元素个数,并在最后更新size值
int i = 0; //遍历顺序表
int * p1 = seq->array; //遍历一遍顺序表
int * p2 = seq->array; //并不全部遍历顺序表,与p1指针合作删除指定元素所有值
//时间复杂度 O(n)
while ( i < ( seq->size ) )
{
if ( x != *p1 )
{
*p2 = *p1;
++p1;
++p2;
++i;
}
else if ( x == *p1 )
{
++p1;
++i;
++count;
}
}
if ( 0 == count )
{
return false; //未找到元素x
}
seq->size = seq->size - count;
return true;
}
/* 改进版冒泡排序(由小到大) */
bool BubbleSort ( SeqList * seq )
{
if ( SeqListIsEmpty ( seq ) )
{
return false;
}
int flag = 1;
int i = 0;
int j = 0;
for ( i = 0; i < ( seq->size ) - 1; ++i )
{
flag = 0;
for ( j = 0; j < ( seq->size ) - i - 1; ++j )
{
if ( seq->array[j] > seq->array[j + 1] )
{
Swap ( &seq->array[j], &seq->array[j + 1] );
flag = 1;
}
else
{
;
}
}
if ( 0 == flag )
{
break;
}
}
return true;
}
/* 改进版选择排序(由大到小) */
bool SelectSort ( SeqList * seq )
{
if ( SeqListIsEmpty ( seq ) )
{
return false;
}
int maxIndex = 0;
int minIndex = seq->size - 1;
int i = 0;
int j = 0;
int temp = seq->size;
for ( i = 0; i < ( temp / 2 ); ++i ) //循环(size/2)次,每次从i开始,第一次执行(size)次,此后每次减2
{
maxIndex = i;
minIndex = seq->size - 1;
for ( j = i; j < seq->size; ++j ) //不能忽略两边元素直接从中间开始遍历
{ //如果从大到小排序 1874763329 忽略两边元素(从第二个元素开始遍历)则变为 8174763392(极端情况下会出错)
if ( seq->array[j] > seq->array[maxIndex] )
{
maxIndex = j;
}
if ( seq->array[j] < seq->array[minIndex] )
{
minIndex = j;
}
}
if ( ( maxIndex == i ) && ( minIndex == seq->size - 1 ) )//不用交换情况
{
;
}
else if ( ( minIndex == i ) && ( maxIndex == seq->size - 1 ) )//交换1次情况
{
Swap ( &seq->array[i], &seq->array[seq->size - 1] );
}
else if ( minIndex == i ) //首元素为最小元素时的情况
{
Swap ( &seq->array[i], &seq->array[maxIndex] );
Swap ( &seq->array[maxIndex], &seq->array[seq->size - 1] );
}
else //一般情况
{
Swap ( &seq->array[i], &seq->array[maxIndex] );
Swap ( &seq->array[seq->size - 1], &seq->array[minIndex] );
}
--seq->size;
}
seq->size = temp;
return true;
}
/* 在seq指向的顺序表中,利用二分查找查找一个元素(返回元素所在位置,未找到返回-1) */
int BinarySearch ( SeqList * seq, DataType x ) //二分查找使用的条件为要查找数据已是有序序列
{
if ( SeqListIsEmpty ( seq ) )
{
return -1;
}
int leftIndex = 0;
int rightIndex = seq->size - 1;
while ( leftIndex <= rightIndex )
{
int midIndex = leftIndex + ( ( rightIndex - leftIndex ) >> 1 );//采用移位操作防止数据太多时产生溢出
if ( x == seq->array[midIndex] )
{
return ( midIndex + 1 );
}
else if ( seq->array[midIndex] > x )
{
rightIndex = midIndex - 1;
}
else if ( seq->array[midIndex] < x )
{
leftIndex = midIndex + 1;
}
}
return -1;
}
/* 在seq指向的顺序表中,利用二分查找查找一个元素(返回元素所在位置,未找到返回-1) */
//int BinarySearch ( SeqList * seq, DataType x, int leftIndex, int rightIndex, int midIndex )//二分查找递归版本
//{
// if ( leftIndex > rightIndex )
// {
// return -1;
// }
//
// if ( x == seq->array[midIndex] )
// {
// return ( midIndex + 1 );
// }
//
// if ( seq->array[midIndex] > x )
// {
// rightIndex = midIndex - 1;
// }
// else if ( seq->array[midIndex] < x )
// {
// leftIndex = midIndex + 1;
// }
//
// midIndex = leftIndex + ( ( rightIndex - leftIndex ) >> 1 );
//
// return ( BinarySearch ( seq, x, leftIndex, rightIndex, midIndex ) );
//}
/* 局部函数定义 */
/* 检查pos值是否合法 */
static bool CheckPos ( SeqList * seq, size_t pos )
{
if ( ( SeqListIsEmpty ( seq ) ) && ( 1 == pos ) )
{
return true; //合法
}
if ( ( 0 == pos ) || ( pos > seq->size ) )
{
return false; //不合法返回false
}
else
{
return true; //合法返回true
}
}
/* 交换函数 */
static bool Swap ( DataType * val1, DataType * val2 )
{
DataType temp = 0;
temp = *val1;
*val1 = *val2;
*val2 = temp;
return true;
}