题目描述:
设顺序表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