顺序表的静态存储c语言实现

本文介绍如何使用C语言实现顺序表的静态存储。通过数组来保存数据,包括两个源文件(sxb.c和test.c)和一个头文件(sxb.h),其中sxb.h声明函数原型和结构,test.c进行程序测试,sxb.c实现具体功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

顺序表的静态存储:

通过数组保存数据,程序分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] );
//}





sxb.h:


/*  顺序表类型的头文件  */


#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;
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值