天天看点

线性表练习----线性表的就地逆置

编程语言:C

编译环境:Dev-C++

题目:设元素值为整型的线性表L,采用顺序结构存储,编写程序,实现线性表的就地逆置

算法思想:已知表长length,经过length/2次循环,将位序为i(1<=i<=length/2)的数据元素与位序为length+1-i的数据元素互换

怎么互换?首先利用函数ListDelete删除第i个数据元素,并用e1返回其值,然后删除第length-i个数据元素,用e2返回其值,这时表长变为length-2

接着利用函数ListInsert将e2插在第i个元素之前,将e1插在第length+1-i个元素之前

用到的函数有:1.InitList 2.ListInsert 3.ListDelete 4.ListTraverse

源代码:

//设元素值为整型的线性表L,采用顺序结构存储,编写程序,实现线性表的就地逆置
//就地逆置举个例子就是将(1,5,3,7,2,6,9)逆置为(9,6,2,7,3,5,1) 
//算法思想:已知表长length,经过length/2次循环,将位序为i(1<=i<=length/2)的数据元素与位序为length+1-i的数据元素互换 
//          怎么互换?首先利用函数ListDelete删除第i个数据元素,并用e1返回其值,然后删除第length-i个数据元素,用e2返回其值,这时表长变为length-2
//                    接着利用函数ListInsert将e2插在第i个元素之前,将e1插在第length+1-i个元素之前
//用到的函数有:1.InitList 2.ListInsert 3.ListDelete 4.ListTraverse
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
//函数结果状态代码
#define OK 1
#define ERROR 0
#define OVERFLOW -1

typedef int Status;
typedef int ElemType;
//线性表的动态分配存储结构
#define LIST_INIT_SIZE 10
#define LISTINCREMENT 5
typedef struct {
	ElemType *elem;//数组基址
	int length;//当前长度 
	int listsize;//当前存储空间 
}SqList; 
//1.构造一个空的顺序表L
Status InitList(SqList *L)
{
	(*L).elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
	if(!(*L).elem) exit(OVERFLOW);//判断
	(*L).length=0;
	(*L).listsize=LIST_INIT_SIZE;
	return OK; 
}  
//2.在L中第i个位置之前插入新的数据元素e,L的长度加1,前提L存在
Status ListInsert(SqList *L,int i,ElemType e)
{
	if(i<1||i>(*L).length+1)
	    return ERROR;
	if((*L).length>=(*L).listsize)
	{
		ElemType *newbase=(ElemType *)realloc((*L).elem,((*L).listsize+LISTINCREMENT)*sizeof(ElemType));
		if(!newbase) exit(OVERFLOW);
		(*L).elem=newbase;
		(*L).listsize+=LISTINCREMENT;
	}
	ElemType *q=(*L).elem+i-1;
	ElemType *p=(*L).elem+(*L).length-1;
	while(p>=q)
	{
		*(p+1)=*p;
		p--;
	}
	*q=e;
	++(*L).length;
	return OK;
}
//3.删除L的第i个数据元素,并用e返回其值,L的长度减1,前提L存在
Status ListDelete(SqList *L,int i,ElemType *e)
{
	if(i<1||i>(*L).length)
	    return ERROR;
	ElemType *q=(*L).elem+i-1;
	ElemType *p=(*L).elem+(*L).length-1;
	*e=*q;
	q++;
	while(q<=p)
	{
		*(q-1)=*q;
		q++;
	}
	--(*L).length;
	return OK;
}
//4.顺序表的遍历:依次访问表中每一个元素,前提L存在
Status ListTraverse(SqList L)
{
	ElemType *p=L.elem;
	int i=1;
	while(i<=L.length)
	{
		printf("%d ",*p);
		if(i%40==0)
		    printf("\n");
		i++;
		p++;
	}
	printf("\n");
	return OK;
}
int main()
{
	SqList L;
	InitList(&L);
	int i,length;
	ElemType e1,e2;
	printf("该顺序表有多少个数据元素?");
	scanf("%d",&length);
	printf("请输入%d个数据元素:\n",length);
	for(i=1;i<=length;i++)
	{
		scanf("%d",&e1);
		ListInsert(&L,i,e1);
	} 
	printf("原顺序表中的元素为:\n");
	ListTraverse(L);
	for(i=1;i<=length/2;i++)
	{
		ListDelete(&L,i,&e1);
		ListDelete(&L,length-i,&e2);
		ListInsert(&L,i,e2);
		ListInsert(&L,length+1-i,e1);
	}
	printf("就地逆置后顺序表中的元素为:\n");
	ListTraverse(L);
	return 0;
}
           

运行结果:

线性表练习----线性表的就地逆置

又用圆周率小数点后1000位试了一下:

线性表练习----线性表的就地逆置
线性表练习----线性表的就地逆置
线性表练习----线性表的就地逆置

其实还是很有趣的!

有任何建议欢迎底下评论,我会努力改进。

继续阅读