/*
程序规范总结:
1.为了程序的简单易读,能用能分开写尽量分开写return(一长串)的存在;
2.摒弃temp除非只采用一次;
3.if后若只有一个语句,建议还是加上{},以防写习惯,检查错误后,编译器检查不出;
4.for{}或if{}后不加分号;
*/
/*
本程序
优点:节约了内存空间
缺点:算法效率不高,因为二次初始化和判断函数要执行
该进:可以将线性表的初始长度设置得大一点
*/
#include <stdio.h>
#include <stdlib.h>//本库包含exit()函数
/***************************************用结构体定义线性表***********************************************/
typedef int ElemType;//定义元素
typedef struct list//注:结构体名list可不写
{
ElemType *elem;//定义元素类型
int listsize;//线性表容量
int length;//线性表当前长度
}Sqlist;//用typdef将list定义为Sqlist,若过这样的话为什么不直接就将结构体名定义为Sqlist ????????????????????????????
/****************************************本程序所用函数声明******************************************/
void Initlist1Sq(Sqlist **,Sqlist *);//初始化函数
void Creat_sq(Sqlist **,Sqlist *);//创建线性表函数
void Insert_sq(Sqlist **,Sqlist *,int,ElemType);//插入函数
void Panduan(Sqlist **,Sqlist *,int);//判断函数
void Initlist2Sq(Sqlist **,Sqlist *);//二次初始化函数
void Display_sq(Sqlist **);//遍历线性表函数
void SearcByElem(Sqlist **,ElemType);//按值查找函数
void SearchByNum(Sqlist **,int);//按序号查找函数
int DeleteByPos(Sqlist **,int);//按值删除函数
void DeleteByElem(Sqlist **,ElemType);//按序号删除函数
void Printf(void);//打印操作提示符函数
/*******************************************主函数实现*************************************************/
int main(void)//本主函数返回值用int(整型)只为实现输入提示X时能中止整个函数
{
int pos;//pose在按序号删除,查找时接收输入
char cmd;//用cmd接收输入的提示符
ElemType temp;//temp在按元素删除,查找时接收输入
Sqlist L;//定义了线性表
Sqlist *Lp;//指针用于存放L的地址
Sqlist **Lpp;//双指针因为在二次初始化时要改变Lp的指向
Sqlist L1;//定义再生表
Sqlist *L1p;
Lp=&L;
Lpp=&Lp;
L1p=&L1;//将再生表的地址赋给L1p指针
Initlist1Sq(Lpp,L1p);//初始化放在前面,因为应用必须要初始化之后,所以这是不可忽略的步骤,不能让用户自己选择
Printf();//输出提示符: P=遍历,I=插入,S=元素查找,s=序号查找,D=元素删除,d=序号删除,X=退出
while(1)//实现程序的重用
{
cmd=getchar();//用getchar接受Printf命令
switch(cmd)
{
case 'I'://I:插入函数Insert_sq的缩写
case 'i':
printf("输入要插元素:");
scanf("%d",&temp);
printf("输入要插位置:");
scanf("%d",&pos);
Insert_sq(Lpp,L1p,pos,temp);
printf("\n");
Display_sq(Lpp);
Printf();
break;
case 'S'://S:元素查找函数SearcByElem的缩写
printf("输入要查元素:");
scanf("%d",&temp);
SearcByElem(Lpp,temp);
printf("\n");
Display_sq(Lpp);
Printf();
break;
case 's'://s:序号查找函数SearchByNum的缩写
printf("输入要查序号:");
scanf("%d",&pos);
SearchByNum(Lpp,pos);
printf("\n");
Display_sq(Lpp);
Printf();
break;
case 'D'://D:元素删除函数DeleteByElem的缩写
printf("输入要删除的元素:");
scanf("%d",&temp);
DeleteByElem(Lpp,temp);
printf("\n");
Display_sq(Lpp);
Printf();
break;
case 'd'://d:序号删除函数DeleteByPos的缩写
printf("输入删除的序号:");
scanf("%d",&pos);
DeleteByPos(Lpp,pos);
printf("\n");
Display_sq(Lpp);
Printf();
break;
case 'X':
case 'x':
free(L.elem);
return 1;
default:break;
}
}
return 1;
}
/****************************************提示函数********************************************************/
void Printf(void)
{
printf("\n\nI=插入,S=元素查找,s=序号查找,D=元素删除,d=序号删除,X=退出\n");
}
/***************************************初始化线性表*******************************************************/
void Initlist1Sq(Sqlist **L,Sqlist * L1p)
{
ElemType MAXSIZE=3;//默认开辟是3个元素的空间
(*L)->elem=(ElemType *)malloc(MAXSIZE*sizeof(ElemType));//为表中元素开辟MAXSIZE个长度ElemType的连续内存,并将首地址发送给(*L)->elem
if(!(*L)->elem)//判断内存开辟是否成功
{
printf("警告:内存分配出错,尝试重新运行程序!");
exit(0);//终止整个程序!
}
(*L)->length=0;//初始化当前长度
(*L)->listsize=MAXSIZE;//初始化表容量
Creat_sq(L,L1p);
}
/****************************************创建线性表*******************************************************/
void Creat_sq(Sqlist **L,Sqlist * L1p)
{
int i=0;
char cd;
ElemType temp;
printf("元素之间用空格符隔开,!表示确定输入,例如:1 2 3! \n");
printf("输入元素:");
do
{
scanf("%d",&temp);
i++;
Insert_sq(L,L1p,i,temp);//插入函数:在第i个位置添加元素temp
cd=getchar();
}while(cd!='!');//这可控制方法过于恶心,怎样实现输入enter就行了?????????????????????????
Display_sq(L);
}
/*****************************36********插入元素操作********************************************************/
void Insert_sq(Sqlist **L,Sqlist * L1p,int pos,ElemType x)
{
int i;
if(pos<1||pos>(*L)->length+1)//判断插入位置是否合法(很明显位置不能小于1,不能大于当前长度+1)
{
printf("(%d)是错误位置!\n",pos);
return ;
}
Panduan(L,L1p,pos);
for(i=(*L)->length;i>pos-2;i--)//给i赋值当前表长度
{
*((*L)->elem+i+1)=*((*L)->elem+i);//把指定位置pos-2后的元素往后移动一个位置,恰好在pos-1处留个空位,插入!
}
*((*L)->elem+pos-1)=x;
(*L)->length++;
}
/******************************************判断函数*************************************************/
void Panduan(Sqlist **L,Sqlist * L1p,int pos)
{
int i=0;
if((*L)->length==(*L)->listsize)//当表中已满,默认再次分配内存,不提示用户
{
Initlist2Sq(L,L1p);
//printf("判断执行正常");
}
}
/*****************************************二次分配内存**********************************************/
void Initlist2Sq(Sqlist **L,Sqlist * L1p)//写本函数的目的只为节约内存空间
{
int i;
ElemType MAXSIZE=3;//默认分配3个元素
L1p->elem=(ElemType *)malloc(((*L)->listsize+MAXSIZE)*sizeof(ElemType));//为再生表中元素开辟连续内存空间,将首地址发送给元素指针
if(!L1p->elem)
{
printf("警告:内存分配出错,请重新运行程序!\n");
exit(0);//开辟不成功?终止整个程序!
}
L1p->length=0;//初始化再生表当前长度
L1p->listsize=((*L)->listsize+MAXSIZE);//初始化再生表容量
for(i=0;i<(*L)->length;i++)//将L表中的元素复制到再生表中
{
*(L1p->elem+i)=*((*L)->elem+i);
L1p->length++;
}
free((*L)->elem);//但凡有机会执行了二次初始化,将原内存表示放掉
(*L)=L1p;
}
/***************************************** 打印线性表*********************************************/
void Display_sq(Sqlist **L)
{
int i=0;
printf("表中元素如下:\n");
do
{
i++;
printf("(%d)\t",i);
}while(i<(*L)->length);
printf("\n");
i=0;
do
{
printf(" %d\t",*((*L)->elem+i));
i++;
}while(i<(*L)->length);
printf("\n");
}
/****************************************** 查找元素*********************************************/
void SearcByElem(Sqlist **L,ElemType x)//功能:查找给定的X元素,并打印序号
{
int i=0;
printf("查到序号如下:\n");
do
{
if(x==*((*L)->elem+i))
{
printf("(%d)\t",i+1);
}
i++;
}while(i<(*L)->length);
printf("\n查找操作完成!\n");
return ;
}
void SearchByNum(Sqlist **L,int n)//功能:查找给定序号的元素,并打印出其值
{
if(n<1||n>(*L)->length)
{
printf("不存在(%d)号元素!\n",n);
printf("查找操作失败!\n");
return;
}
printf("(%d)号元素值: %d\n",n,*((*L)->elem+n-1));
printf("查找操作完成!\n");
return;
}
/*******************************************删除元素************************************/
int DeleteByPos(Sqlist **L,int pos)
{
int i;
i=pos;
if(pos<1||pos>(*L)->length)
{
printf("删除序号(%d)不存在!\n",pos);
printf("删除操作失败!\n");
return 0;
}
do
{
*((*L)->elem+i-1)=*((*L)->elem+i);
i++;
}while(i<(*L)->length);
(*L)->length--;
printf("删除操作成功!\n");
return 1;
}
void DeleteByElem(Sqlist **L,ElemType temp)
{
int i=0;
int j=0;
do{
if(temp==*((*L)->elem+i))
{
printf("(%d)号等值元素删除操作成功!\n",i+1);
do
{
*((*L)->elem+j-1)=*((*L)->elem+j);
j++;
}while(j<(*L)->length);
(*L)->length--;
i--;
}
i++;
}while(i<(*L)->length);
printf("不存在该元素!\n");
printf("删除操作失败!\n");
}