顺序表的数组形式 和链表形式

数组形式:(如下)

/*顺序表的数组形式*/
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>
#define OK 1
#define ERROR 0
#define OVERFLOW -2//作为越界的处理返回值

typedef int Status;	//返回状态类型
typedef int ElemType;	//可定义的数据类型

#define MAXSIZE 100
typedef struct {
	ElemType elem[MAXSIZE];//基地址,大小确定
	int length;
}SqList;

Status InitList_Sq(SqList &L);//初始化
void LocateElem_Sq(SqList &L,ElemType e);//查找
Status ListInsert_Sq(SqList &L,int i,ElemType e);//插入
Status ListDelete_Sq(SqList &L,int i,ElemType e);//删除
void menu(void);//菜单
void clrscr(void);//清屏
int judje(SqList &L);//判断是否开始顺序正确

int main(void)
{
	printf("\n**********欢迎来到顺序表功能程序**********\n\n\n");
	SqList L;
	int i,res,seat1,number1,seat2,number2,choose,size;
	menu();
	choose=-1;
	L.length=0;
	while(choose!=7)
	{
		printf("\n请输入您的选择:");
		scanf("%d",&choose);
		switch(choose)
		{
		case 1:
			//建立顺序表
			if(InitList_Sq(L))
				printf("\n成功建立顺序表!\n");
			else
				printf("\n顺序表建立失败!\n");
			break;
		case 2:
			//输入数据
			clrscr();
			printf("\n请选择输入大小(0<size<=100):");
			scanf("%d",&size);
			printf("\n开始输入:\n");
			for(i=0;i<size;++i)
			{
				printf("L.elem[%d]=",i);
				scanf("%d",&L.elem[i]);
				printf("\n");
			}
			L.length=size;
			printf("\n");
			menu();
			break;
		case 3:
			//查找
		//	judje(L);下面将进行改进
			if(judje(L)==8)
				break;
			clrscr();
			printf("\n请输入要查找的数:");
			scanf("%d",&number2);
			/*temp=*/
			/*temp=*/
			LocateElem_Sq(L,number2);
			//if(temp!=0)
				//printf("\n该元素(%d)是第%d个\n",number2,temp);
			//else//本来就是返回0,但是bug保险期间,直接else更好
				//printf("\n查找失败,里面没有该元素(%d)\n",number2);
			menu();
			break;
		case 4:
			//插入
			if(judje(L)==8)
				break;
			clrscr();
			printf("\n请输入插入的位置,我们将在该位置前插入\n");
			scanf("%d",&seat1);
			printf("请输入插入的元素:");
			scanf("%d",&number1);
			if(ListInsert_Sq(L,seat1,number1))
				printf("\n插入成功!\n");
			else
				printf("\n插入失败!\n");
			menu();
			break;
		case 5:
			//删除
			if(judje(L)==8)
				break;
			clrscr();
			printf("\n请输入需要删除的数的位置:");
			scanf("%d",&seat2);
			if(ListDelete_Sq(L,seat2,res))
				printf("\n删除成功!\n被删除的数是:%d\n",L.elem[seat2-1]);
			else
			{
				if(seat2>L.length)
					printf("\n过界,删除失败!\n");
				if(seat2<=0)
					printf("\n输入不合法!\n");
				else
					printf("\n输入有误!\n");
			}
			menu();
			break;
		case 6:
			//输出数据
			if(judje(L)==8)
				break;
			clrscr();
			printf("\n当前的顺序表为:\n");
			for(i=0;i<L.length;++i)
			{
				printf("L.elem[%d]=%d	",i,L.elem[i]);
				if((i+1)%5==0)//5个一行
					printf("\n");
			}
			menu();
			break;
		case 7:
			//退出
			clrscr();
			printf("\n\n程序2秒后即将退出,祝您生活愉快!\n");
			Sleep(2000);
			exit(0);
		default ://消除隐患
			printf("\n出现错误!无该功能选项!\n");
			printf("请重新输入\n");
			exit(0);
		}
	}
	return 0;
}

Status InitList_Sq(SqList &L)
{
	//初始化顺序表
	if(!L.elem)	//如果数组创建失败
		exit(OVERFLOW);
	L.length=0;//数组创建成功的话,就初始化表长为0
	return OK;
}

void LocateElem_Sq(SqList &L,ElemType e)//按位置寻找
{
	//查找元素,e代表需要查找的元素
	int k=0, j=0;
	for(int i=0;i<L.length;++i)
		if(L.elem[i]==e)
		{//return (i+1);
			j++;
			printf("第%d个这个数(%d)位于第%d个\n",j,e,(i+1));
			k++;
		}
		if(k==0)
			printf("抱歉,没有找到!\n");
}

Status ListInsert_Sq(SqList &L,int i,ElemType e)//插入
{
	//顺序表的插入操作,i代表第几个元素,操作为在第i个元素的前面插入
	//所以i的取值范围是:	1<=i<=L.length+1
	if(i<1 || i>L.length+1) 
	{
		printf("\n输入范围有误!\n");
		return ERROR;//无效位置
	}
	if(L.length==MAXSIZE)
		return ERROR;//判断是否已经慢
	for(int j=L.length-1;j>=i-1;--j)//有数值才会有length
		L.elem[j+1]=L.elem[j];
	L.elem[i-1]=e;
	L.length++;
	return OK;
}

Status ListDelete_Sq(SqList &L,int i,int res)
{
	//顺序表的删除,删除第i个元素,e中保留被删除的元素值
	//所以i的取值范围是	1<=i<=L.length
	if(i<1 || i>L.length) 
		return ERROR;
	res=L.elem[i-1];//!!!!!!!!!!!!!!!!出现位置原因bug!!!!!!!!!!!!!!!!!!!!!!!!!!!
	for(int j=i-1;j<=L.length-1;++j)
		L.elem[j]=L.elem[j+1];
	--L.length;
	return OK;
}

void menu(void)
{
	//
	printf("\n*****最前头序号代表功能!*****\n");
	printf("1.建立顺序表	2.输入数据	3.查找\n");
	printf("4.插入		5.删除		6.输出数据\n		7.退出\n\n");
}

void clrscr(void)
{
	system("cls");
}

int judje(SqList &L)//防止不会的人开始一来根本不会操作顺序
{
	if(L.length==0)
	{	
		printf("\n还未初始化哦!\n");
		//exit(0);
		return 8;
	}
	return 0;
}

链表形式:(如下)

/*顺序表的链表形式*/
/*传的时候不要忘记将头文件也一起传输过去(wangjie.h)(后面不要忘记加上kaishi()函数去使用)*/
/*代码实现的功能更多,所以要长那么一些*/
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef int ElemType;

typedef struct LNode{//创建节点
	ElemType data;	//数据域
	struct LNode *next;	//指针域 自引用
}LNode,*LinkList;
int k=0;
int length1=0;//用于记录元素个数
int ddd=0;
void menu(void);//菜单
void clrscr(void);//清屏
Status InitList_L(LinkList &L);//建立链表
void CreateList_F(LinkList &L,int n);//前插法建立单链表
Status GetElem_L(LinkList L,int i,ElemType &e);//按序号查找
LNode *LocateElem_L(LinkList L,ElemType e);//按值查找
Status ListInsert_L(LinkList &L,int i,ElemType e);//单链表的插入
Status ListDelete_L(LinkList &L,int i,ElemType e);//单链表的删除
void judje();//判断链表是否已经初始化
void huanying(void);
//void panduan();//


void huanying(void)
{
	puts("			           ***");
	puts("			          **");
	puts("			******** **************");
	puts("			******* ** ************");
	puts("			 *  ** **  **      ***");
	puts("			 ** * ***  **     ***");
	puts("			  ***     ****   **");
	puts("			 ** **   ** ***");
	puts("			**   *  **   ***");
	puts("			       **       ***");
	puts("			      ***        ****");
	puts("			**");
	puts("			 **       *** ********");
	puts("			  *      **** ********");
	puts("			******  ***   **    **");
	puts("			******  **    **   **");
	puts("			    **  **    **   **");
	puts("			   **   **    **");
	puts("				**   **    **");
	puts("			 **     ***** **");
	puts("			   **         **");
	puts("			  **");
	puts("			**************************");
	puts("			**************************");
	Sleep(2000);
	system("cls");
	
}

int judje(LinkList &L)//判断链表是否已经初始化
{
	if(k==1) return 0;//如果k=0的话直接就出去
	if(L)//如果头指针指向为空的话就说明没有初始化成功
	{
		printf("链表还未初始化!\n");
		puts("请先初始化(即建立链表)");
		int ddd=1;
	}
	else//初始化成功处理
	{
		printf("\n");
	}
	return 0;
}

Status InitList_L(LinkList &L)
{
	L=(struct LNode*)malloc(sizeof(struct LNode));//申请新节点
	L->next=NULL;
	k=1;
	return OK;
}

void menu(void)//菜单
{
	//
	printf("\n*****建立链表系统*****\n");
	printf("序号为功能选择!\n");
	printf("1.建立链表	2.输入数据	3.按位置查找	4.按值查找\n");
	printf("5.链表的插入	6.链表的删除	7.输出数据	8.人工清屏	0.退出\n");
}

void clrscr(void)//清屏
{
	system("cls");
}

void CreateList_F(LinkList &L,int n)//前插法建立单链表
{
	//逆位序,n代表大小,L代表头节点
	LNode *p;
	L=(struct LNode*)malloc(sizeof(struct LNode));
	L->next=NULL;
	for(int i=0;i<n;++i)
	{
		p=(struct LNode*)malloc(sizeof(struct LNode));
		printf("请输入第%d个数据(回车确认):",i+1);
		scanf("%d",&p->data);
		printf("\n");
		p->next=L->next; L->next=p;//实现链表移动代码
	}
}

void CreateList_L(LinkList &L,int n)//后插法建立单链表
{
	//同上理,不同的是本为正序
	LNode *r, *p;
	L=(struct LNode*)malloc(sizeof(struct LNode));
	L->next=NULL;
	r=L;
	for(int i=0;i<n;++i)
	{
		p=(struct LNode*)malloc(sizeof(struct LNode));
		printf("请输入第%d个数据(回车确认):",i+1);
		scanf("%d",&p->data);
		printf("\n");
		p->next=NULL; r->next=p; r=p;//实现链表移动代码
	}
}

Status GetElem_L(LinkList L,int i,ElemType &e)//按序号查找
{
	//
	int j=0;
	LNode *p;
	p=L->next;j=1;
	while(j<i && p)//实现后移查找
	{
		p=p->next;
		++j;
	}
	if(!p || j>i)
	{
		printf("输入有误!\n");
		return 0;
	}
	e=p->data;
	return OK;
}

LNode *LocateElem_L(LinkList L,ElemType e)//按值查找
{
	//
	int wj=1;
	int length=0;//方便记录第几个
	LNode *p;
	p=L->next; length=1;
	do{
		while(p && p->data!=e)//直到找到了e或则走完了链表才会跳出while()循环
		{
			p=p->next;
			++length;
		}
		//成功过了上面的那个while()循环
		//puts("真的可以吗?");
		if(/*p->data==e &&*/ p)
		{
			printf("第%d次查找成功",wj);
			printf("第%d个该元素位于第%d个\n",wj,length);
			wj++;
			p=p->next;
			length++;
		}
		//puts("好的吗?");
		if((length-1)>length1)
		{
			printf("查找失败,没有找到元素%d",e);
			return 0;
		}
	}while((length-1)!=length1);
	return p;
}

Status ListInsert_L(LinkList &L,int i,ElemType e)//单链表的插入
{
	//
	int j=0;
	LNode *p,*s;
	p=L;
	while(p && j<i-1)
	{
		p=p->next;
		++j;
	}
	if(!p || j>i-1) return ERROR;
	s=(struct LNode*)malloc(sizeof(struct LNode));
	s->data=e;//先带上数值
	s->next=p->next;//开始实现插入
	p->next=s;
	length1++;
	return OK;
}

Status ListDelete_L(LinkList &L,int i,ElemType *e)//单链表的删除*****bug********
{
	//
	LNode *p,*q;
	int j=0;
	p=L;
	while(p->next && j<i-1)//p->next是确保不是最后一个也移动了
	{
		p=p->next;
		++j;
	}
	if(!(p->next) || j>i-1) return ERROR;
	q=p->next;
	p->next=q->next;
	printf("被删除的数是:%d",q->data);
	free(q);
	length1--;
	return OK;
}

int main(void)
{
	//
	int res, seat1, number2, choose, choose1, number1;
	LNode *L, *p;
	int *qq=NULL;
	system("color F1");
	huanying();
	printf("\n*****欢迎来到单链表的应用程序*****\n");
	printf("你准备好了吗?\n");
	system("pause");
	menu();
	choose=-1;
	int n=1;//用于case7
	while(choose!=0)
	{
		printf("请选择功能(输入序号):");
		scanf("%d",&choose);
		printf("\n");
		switch(choose)
		{
		case 0:
			//
			printf("程序结束!\n");
			puts("祝您生活愉快!");
			break;
		case 1:
			if(InitList_L(L)!=NULL)
				printf("申请空间成功,成功建立链表\n");
			else{
				printf("申请空间失败\n");
				exit(0);
			}
			//printf("1秒后开始程序!\n");此行代码主要是为了骗使用者此程序真的在努力运行,实则在平时使用中无所谓
			//Sleep(1000);
			ddd=1;
			break;
		case 2:
			judje(L);
			if(ddd==1)
			{
				clrscr();
				printf("请问是采用前插法(输入1)还是后插法(输入2):");
xuanze:
				scanf("%d",&choose1);
				if(choose1!=1 && choose1!=2)
				{
					puts("输出有误!请在1和2之间进行选择");
					printf("你的选择是:");
					goto xuanze;
				}
				printf("\n");
				printf("请选择空间大小(1~128):");
				scanf("%d",&number1);
				length1=number1;//记录元素个数
				printf("\n");
				if(choose1==1)
					CreateList_F(L,number1);//前插法
				if(choose1==2)
					CreateList_L(L,number1);//后插法
				printf("链表建立完成\n");
				menu();
			}
			else
				break;
			break;
			//
		case 3:
			//
			judje(L);
			if(ddd==1)
			{
				clrscr();
				printf("请输入你想要查找第几个位置的元素(现在一共有%d个元素):",length1);
				scanf("%d",&seat1);
				printf("\n");
				if(GetElem_L(L,seat1,res))
					printf("查找成功!\n第%d个元素是%d\n",seat1,res);
				else
					printf("查找失败!\n");
				menu();
			}
			else 
				break;
			break;
		case 4:
			//出现了没有该数据就显现“出局”的bug
			judje(L);
			if(ddd==1)
			{
				clrscr();
				menu();
				printf("输入一个值来查找:");
				scanf("%d",&number2);
				printf("\n");
				if(LocateElem_L(L,number2)!=p)
					//{
					printf("\n");
				//	}
				//else 
				//	printf("查找失败\n没有找到%d\n",number2);
			}
			else
				break;
			break;
		case 5:
			//此处seat1代表插入的位置(之前),number2代表插入的数值
			judje(L);
			if(ddd==1)
			{
				clrscr();
				menu();
				printf("请输入插入的位置(之前):");
				scanf("%d",&seat1);
				printf("\n");
				printf("请输入插入的数值:");
				scanf("%d",&number2);
				printf("\n");
				if(ListInsert_L(L,seat1,number2))
					printf("已成功将%d插入到第%d个元素之前!\n",number2,seat1);
				else
					printf("插入失败\n");
			}
			else
				break;
			break;
		case 6:
			//
			judje(L);
			if(ddd==1)
			{
				clrscr();
				menu();
				printf("请输入一个位置来删除:");
				scanf("%d",&seat1);
				printf("\n");
				if(ListDelete_L(L,seat1,qq))//qq被当成废物去传参了
					//printf("删除成功!\n被删除的数是%d\n",*qq);
					printf("\n删除成功!\n");
				else
					printf("\n删除失败!\n");
			}
			else 
				break;
			break;
		case 7:
			//
			judje(L);
			n=0;//用于重新建立链表时输出分行出现问题
			if(ddd==1)
			{
				clrscr();
				menu();
				printf("链表的输出如下:\n");
				p=L->next;
				printf("************************************\n\n");
				while(p)
				{
					++n;
					printf("%-5d ",p->data);
					if(n%5==0)
						printf("\n");
					p=p->next;
				}
				printf("\n************************************\n");
			}
			else 
				break;
			break;
		case 8:
			//人工清屏功能
			printf("\n1秒后清屏\n");
			Sleep(1000);
			clrscr();
			menu();
			break;
		default:
			//
			printf("输入有误!\n");
			printf("请重新输入!\n");
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值