数据结构c语言版 严蔚敏 (将x插入到递增序列va中)

题目描述:

设顺序表va中的数据元素递增有序。试写一算法,将x插入到顺序表的适当位置上,以保持该表的有序性。

思路分析:

C语言代码实现:

头文件

  • Status.h(相关状态码及宏函数列表)
/**********************************
 *                                *
 * 文件夹: ▲01 绪论              *
 *                                *
 * 文件名: Status.h               *
 *                                *
 * 内  容: 相关状态码及宏函数列表 *
 *                                *
 **********************************/ 

#ifndef STATUS_H
#define STATUS_H

/* 状态码 */
#define	TRUE		1			//真 
#define	FALSE		0			//假
#define YES			1			//是
#define NO          0			//否 
#define	OK			1			//通过
#define	ERROR		0			//错误
#define SUCCESS		1			//成功 
#define UNSUCCESS	0			//失败 
#define	INFEASIBLE	-1			//不可行

#ifndef _MATH_H_ 				//系统中已有此状态码定义,要避免冲突 
#define	OVERFLOW	-2			//堆栈上溢
#define UNDERFLOW	-3			//堆栈下溢
#endif 

#ifndef NULL
#define NULL ((void*)0)
#endif

/* 状态码识别类型 */
typedef int Status;

/*宏函数*/
//函数暂停一段时间
#define Wait(x)\
 {\
	double _Loop_Num_;\
	for(_Loop_Num_=0.01; _Loop_Num_<=100000.0*x; _Loop_Num_+=0.01)\
		;\
 }//设立一个空循环 

//摁Enter键继续 
#define PressEnter\
 {\
	fflush(stdin);\
	printf("Press Enter...");\
	getchar();\
	fflush(stdin);\
 }
#endif
  • SequenceList.c
/***************************************
 *                                     *
 * 文件夹: ▲02 线性表\01 SequenceList *
 *                                     *
 * 文件名: SequenceList.c              *
 *                                     *
 * 算  法: 2.3、2.4、2.5、2.6          * 
 *                                     *
 ***************************************/

#ifndef SEQUENCELIST_C
#define SEQUENCELIST_C

#include "SequenceList.h" 				//**▲02 线性表**//

/*════╗
║算法2.3 ║ 
╚════*/
Status InitList_Sq(SqList *L)
{
	(*L).elem = (LElemType_Sq*)malloc(LIST_INIT_SIZE*sizeof(LElemType_Sq));
	if(!(*L).elem)
		exit(OVERFLOW); 				//分配内存失败

	(*L).length = 0;					//初始化顺序表长度为0
	(*L).listsize = LIST_INIT_SIZE;		//顺序表初始内存分配量

	return OK;							//初始化成功	 
} 

void ClearList_Sq(SqList *L)
{
	(*L).length = 0;
}

void DestroyList_Sq(SqList *L)
{
	free((*L).elem);

	(*L).elem = NULL;					//释放内存后置空指针 
	(*L).length = 0;
	(*L).listsize = 0;
}

Status ListEmpty_Sq(SqList L)
{
	return 	L.length==0 ? TRUE : FALSE;
}

int ListLength_Sq(SqList L)
{
	return L.length;	
}

Status GetElem_Sq(SqList L, int i, LElemType_Sq *e)
{ 
	if(i<1 || i>L.length)
		return ERROR;					//i值不合法
	else
		*e = L.elem[i-1];

	return OK;
}

/*════╗
║算法2.6 ║ 
╚════*/
int LocateElem_Sq(SqList L, LElemType_Sq e, Status(Compare)(LElemType_Sq, LElemType_Sq))
{
	int i = 1;							//i的初值为第一个元素的位序
	
	while(i<=L.length && !Compare(e, L.elem[i-1]))
		++i;

	if(i<=L.length)
		return i;
	else
		return 0; 
}

Status PriorElem_Sq(SqList L, LElemType_Sq cur_e, LElemType_Sq *pre_e)
{
	int i = 1;
	
	if(L.elem[0]!=cur_e)				//第一个结点无前驱 
	{
		while(i<L.length && L.elem[i]!=cur_e)
			++i;
		
		if(i<L.length)
		{
			*pre_e = L.elem[i-1];
			return OK;
		}	
	}
			
	return ERROR;
}

Status NextElem_Sq(SqList L, LElemType_Sq cur_e, LElemType_Sq *next_e)
{
	int i = 0;
	
	while(i<L.length && L.elem[i]!=cur_e)
		++i;

	if(i<L.length-1)					//最后一个结点无后继 
	{
		*next_e = L.elem[i+1];	
		return OK;
	}

	return ERROR;
}

/*════╗
║算法2.4 ║ 
╚════*/
Status ListInsert_Sq(SqList *L, int i, LElemType_Sq e)
{
	LElemType_Sq *newbase; 
	LElemType_Sq *p, *q;

	if(i<1 || i>(*L).length+1)
		return ERROR;					//i值不合法

	if((*L).length >= (*L).listsize)	//若存储空间已满,需开辟新空间 
	{
		newbase = (LElemType_Sq*)realloc((*L).elem, ((*L).listsize+LISTINCREMENT)*sizeof(LElemType_Sq));
		if(!newbase)
			exit(OVERFLOW);

		(*L).elem = newbase;
		(*L).listsize += LISTINCREMENT;
	}
	
	q = &(*L).elem[i-1];				//q为插入位置 
	
	for(p=&(*L).elem[(*L).length-1]; p>=q; --p)
		*(p+1) = *p;					//插入位置及之后的元素右移 
	
	*q = e;								//插入e 
	(*L).length++;						//表长增1

	return OK; 
}

/*════╗
║算法2.5 ║ 
╚════*/
Status ListDelete_Sq(SqList *L, int i, LElemType_Sq *e)
{
	LElemType_Sq *p, *q;
		
	if(i<1 || i>(*L).length)
		return ERROR;					//i值不合法
	
	p = &(*L).elem[i-1];				//p为被删除元素的位置 
	*e = *p;
	q = (*L).elem+(*L).length-1; 		//表尾元素位置 
	
	for(++p; p<=q; ++p)
		*(p-1) = *p;					//被删元素之后的元素左移 

	(*L).length--;						//表长减1

	return OK;
}

Status ListTraverse_Sq(SqList L, void(Visit)(LElemType_Sq))
{
	int i;

	for(i=0; i<L.length; i++)
		Visit(L.elem[i]);
	return OK;
}
#endif
  • SequenceList.h
/***************************************
 * 文件夹: ▲02 线性表\01 SequenceList *
 * 文件名: SequenceList.h              *
 * 内  容: 顺序表相关操作列表          *
 ***************************************/
#ifndef SEQUENCELIST_H
#define SEQUENCELIST_H

#include <stdio.h>
#include <stdlib.h>						//提供malloc、realloc、free、exit原型
#include "Status.h"		//**▲01 绪论**//

/* 宏定义 */
#define LIST_INIT_SIZE 100				//顺序表存储空间的初始分配量
#define LISTINCREMENT  10				//顺序表存储空间的分配增量

/* 顺序表类型定义 */
#ifndef LELEMTYPE_SQ
#define LELEMTYPE_SQ
typedef int LElemType_Sq;
#endif

typedef struct
{
	LElemType_Sq *elem;					//存储空间基址(指向第一个结点的指针)
	int length;							//当前顺序表长度
	int listsize;						//当前分配的存储容量
}SqList;								//顺序表0号单元正常使用

/* 顺序表函数列表 */
Status InitList_Sq(SqList *L);
/*━━━━━━━━━━━━━━━┓
┃(01)算法2.3:初始化空顺序表L。┃
┗━━━━━━━━━━━━━━━*/

void ClearList_Sq(SqList *L);
/*━━━━━━━━━┓
┃(02)清空顺序表L。 ┃
┗━━━━━━━━━*/

void DestroyList_Sq(SqList *L);
/*━━━━━━━━━┓
┃(03)销毁顺序表L。 ┃
┗━━━━━━━━━*/

Status ListEmpty_Sq(SqList L);
/*━━━━━━━━━━━━━┓
┃(04)判断顺序表L是否为空。 ┃
┗━━━━━━━━━━━━━*/

int ListLength_Sq(SqList L);
/*━━━━━━━━━━━━━━┓
┃(05)返回顺序表L中元素个数。 ┃
┗━━━━━━━━━━━━━━*/

Status GetElem_Sq(SqList L, int i, LElemType_Sq *e);
/*━━━━━━━━━━━━━━━━┓
┃(06)用e接收顺序表L中第i个元素。 ┃
┗━━━━━━━━━━━━━━━━*/

int LocateElem_Sq(SqList L, LElemType_Sq e, Status(Compare)(LElemType_Sq, LElemType_Sq));
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃(07)算法2.6:返回顺序表L中首个与e满足Compare关系的元素位序。┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/

Status PriorElem_Sq(SqList L, LElemType_Sq cur_e, LElemType_Sq *pre_e);
/*━━━━━━━━━━━━━━━━━┓
┃(08)用pre_e接收cur_e的前驱。      ┃
┗━━━━━━━━━━━━━━━━━*/

Status NextElem_Sq(SqList L, LElemType_Sq cur_e, LElemType_Sq *next_e);
/*━━━━━━━━━━━━━━━━━┓
┃(09)用next_e接收cur_e的后继。     ┃
┗━━━━━━━━━━━━━━━━━*/

Status ListInsert_Sq(SqList *L, int i, LElemType_Sq e);
/*━━━━━━━━━━━━━━━━━━━━━┓
┃(10)算法2.4:在顺序表L的第i个位置上插入e。┃
┗━━━━━━━━━━━━━━━━━━━━━*/

Status ListDelete_Sq(SqList *L, int i, LElemType_Sq *e);
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃(11)算法2.5:删除顺序表L上第i个位置的元素,并用e返回。┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━*/

Status ListTraverse_Sq(SqList L, void (Visit)(LElemType_Sq));
/*━━━━━━━━━━━━━━┓
┃(12)用visit函数访问顺序表L。┃
┗━━━━━━━━━━━━━━*/
#endif

#####################################################

主函数:

Question-2.11-main.c

#include <stdio.h>
#include <stdlib.h>											//提供malloc、realloc、free、exit原型
#include "../../../▲课本算法实现/▲01 绪论/Status.h"  							//**▲01 绪论**//
#include "../../../▲课本算法实现/▲02 线性表/01 SequenceList/SequenceList.c"	//**▲02 线性表**//

/* 函数原型 */
Status Algo_2_11(SqList *va, LElemType_Sq x);
	
void PrintElem(LElemType_Sq e);
	//测试函数,打印整型 

int main(int argc, char *argv[])
{
	SqList L;
	int i;
	
	if(InitList_Sq(&L))					//链表L创建成功
	{
		for(i=1; i<=10; i++)			//链表L中元素1~20 
			ListInsert_Sq(&L, i, 2*i);	
	}
	
	printf("L = ");
	ListTraverse_Sq(L, PrintElem); 			//输出L
	printf("\n\n");	
	
	printf("将元素 \"5\" 插入到链表L中...\n"); 
	Algo_2_11(&L, 5);
	printf("此时L = ");
	ListTraverse_Sq(L, PrintElem); 			//输出L
	printf("\n\n");
		
	return 0;
}

/*━━━━━━━━━━━━━━━┓
┃题2.11:将x插入到递增序列va中 ┃
┗━━━━━━━━━━━━━━━*/
Status Algo_2_11(SqList *va, LElemType_Sq x)
{
	int i;
	LElemType_Sq *newbase;
	
	if(!(*va).length)
		return ERROR;
	
	if((*va).length==(*va).listsize)	//若存储空间已满,需开辟新空间 
	{
		newbase = (LElemType_Sq*)realloc((*va).elem, ((*va).listsize+LISTINCREMENT)*sizeof(LElemType_Sq));
		if(!newbase)
			exit(OVERFLOW);

		(*va).elem = newbase;
		(*va).listsize += LISTINCREMENT;
	}
	
	for(i=(*va).length; i>=1; i--)
	{
		if((*va).elem[i-1]>x)
			(*va).elem[i] = (*va).elem[i-1];
		else	
			break;
	}
	
	(*va).elem[i] = x;
	(*va).length++;
	
	return OK;
}

void PrintElem(LElemType_Sq e)
{
	printf("%d ", e);
}

#####################################################3

实现结果:

在这里插入图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值