线性表的顺序表示和实现

头文件c.h

#pragma once
#include <stdio.h>
#include <stdlib.h>

//函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1

typedef int Status;								//Status是函数的类型,其值是函数结果状态代码,如OK等
typedef int Boolean;							//Boolean是布尔类型,其值是TURE或FALSE

#define LIST_INIT_SIZE 10						//线性表存储空间的初始分配量
#define LISTINCREMENT 2							//线性表存储空间的分配增量

algorithm.h

#pragma once
#include "c.h"
#include "estimate.h"

//定义一个结构体
typedef struct sqList
{
	int * pElem;									//存储空间基址
	int length;										//当前长度
	int listsize;									//当前分配的存储容量(以sizeof(ElemType)为单位)
}SQLIST, * PSQLIST;

//函数声明
Status initList(SQLIST *list);
Status listInsert(PSQLIST list, int i, int e);
Status listEmpty(PSQLIST list);
Status clearList(PSQLIST list);
Status getElem(PSQLIST list, int i, int *e);
int locateElem(PSQLIST list, int e, Status(*compare) (int i, int j));
Status priorElem(PSQLIST list, int cur_e, int * pre_e);
Status nextElem(PSQLIST list, int cur_e, int * next_e);
int listLength(PSQLIST list);
Status listDelete(PSQLIST list, int i, int *e);
Status listTraverse(PSQLIST list);
Status destroyList(PSQLIST list);

estimate.h

#include "c.h"

Status comp(int c1, int c2);
数据元素判定函数(平方关系):

#include "c.h"

Status comp(int c1, int c2)					//数据元素判定函数(平方关系)
{
	if (c1 == c2*c2) 
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}

线性表操作函数algorithm.c:

#include "c.h"
#include "algorithm.h"					//包含这个头文件,它也就实际上包含了函数的声明

//构造一个空的顺序线性表
Status initList(SQLIST *list)
{
	list->pElem = (int *)malloc(LIST_INIT_SIZE * sizeof(int));

	if (NULL == list->pElem) {
		printf("内存分配失败!\n");
		exit (-1);
	}

	list->length = 0;								//空表长度为0
	list->listsize = LIST_INIT_SIZE;				//初始存储容量

	return OK;
}


//初始条件:线性表已存在。操作结果:销毁顺序线性表list
Status destroyList(PSQLIST list)
{
	free (list->pElem);
	list->pElem = NULL;
	list->length = 0;
	list->listsize = 0;

	return OK;
}

//初始条件:顺序线性表list已存在。操作结果:将list置为空表
Status clearList(PSQLIST list)
{
	list->length = 0;

	return OK;
}

//初始条件:顺序线性表list已存在。操作结果:如果list为空表,则返回TURE,否则返回FALSE
Status listEmpty(PSQLIST list)
{
	if (0 == list->length)
	{
		return TRUE;
	} 
	else
	{
		return FALSE;
	}
}

//初始条件:顺序线性表list已存在。操作结果:返回list中数据元素个数
int listLength(PSQLIST list) 
{
	return list->length;
}

//初始条件:顺序线性表已存在,1<<i<<listLength(list)
//操作结果:用e返回list中第i个数据元素的值
Status getElem(PSQLIST list, int i, int *e) {
	if (i < 1 || i > list->length)
	{
		exit (-1);
	} 
	else 
	{
		*e = list->pElem[i-1];
		return OK;
	}
}
/*
//初始条件:顺序线性表list已存在,compare()是数据元素判定函数(满足为1,否则为0)
//操作结果:返回list中第1个与e满足关系compare()的数据元素位序。
//若这样的数据元素不存在,则返回值为0。
int locateElem(PSQLIST list, int e) {
	int * p;
	int i = 1;					//i的初值为第一个元素的位序
	p = list->pElem;			//p的初值为第一个元素的存储位置
	
	while (i < list->length && !comp(*(p++), e))
	{
		++i;	
	}

	if (i <= list->length)
	{						//满足关系
		return i;
	} 
	else
	{
		return 0;
	}
}
*/

//初始条件:顺序线性表list已存在
//操作结果:若cur_e是list的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败,pre_e无定义
Status priorElem(PSQLIST list, int cur_e, int * pre_e)
{
	int i = 2;
	int * p = list->pElem + 1;						//从第二个元素开始

	while (i <= list->length && *p != cur_e)
	{
		p++;
		i++;
	}

	if (i > list->length) 
	{
		return INFEASIBLE;
	} 
	else
	{
		* pre_e = *(--p);

		return OK;
	}
}

//初始条件:顺序线性表list已存在
//操作结果:若cur_e是list的数据元素,且不是最后一个,则用next_e返回它的后继,否则操作失败,next_e无定义
Status nextElem(PSQLIST list, int cur_e, int * next_e)
{
	int i = 1;
	int * p = list->pElem;

	while (i < list->length && *p != cur_e)
	{
		i++;
		p++;
	}

	if (i == list->length)
	{					//已经是最后一项了
		return INFEASIBLE;
	} 
	else 
	{
		* next_e = *(++p);						//注意这里必须是++p
		return OK;	
	}
}


//初始条件 顺序线性表list已存在,1<<i<<list->length+1
//操作结果:在List中第i个位置之前插入新的数据元素e,list的长度加1
Status listInsert(PSQLIST list, int i, int e)
{
	int * newBase;
	int * p;
	int * q;

	if (i < 1 || i > list->length+1) 
	{					//i值不合法
		return ERROR;
	}

	//当前存储空间已满,增加分配
	if (list->length >= list->listsize)
	{
		newBase = (int *)realloc (list->pElem, (list->listsize + LISTINCREMENT) * sizeof (int));
		if (NULL == newBase) 
		{
			printf ("存储分配失败!\n");
			exit (-1);
		}

		list->pElem = newBase;							//新机制
		list->listsize += LISTINCREMENT;				//增加存储容量
	}

	q = list->pElem + i -1;								//q为插入位置

	for (p=list->pElem+list->length-1; p>=q; p--)		//插入位置及之后的元素右移
	{
		*(p+1) = *p;
	}
	*q = e;												//插入e
	++list->length;										//表长增1

	return OK;
}


//初始条件 顺序线性表list已存在,1<<i<<list->length
//操作结果:删除list的第i个数据元素,并用e返回其值,list的长度减1
Status listDelete(PSQLIST list, int i, int *e) 
{
	int *p;
	int *q;

	if ((i<1) || (i>list->length))						//i值不合法
	{
		return ERROR;
	}

	p = list->pElem + i - 1;							//p为被删除元素的位置
	*e = *p;												//被删除元素的值赋给e

	q = list->pElem + list->length - 1;					//表尾的位置
	for (++p; p<=q; ++p)
	{
		*(p-1) = *p;	
	}
	list->length--;

	return OK;
}

//遍历
Status listTraverse(PSQLIST list)
{
	int *p;
	int i;
	p = list->pElem;

	for (i=0; i<list->length; i++)
	{
		printf ("%d", list->pElem[i]);
	}

	return OK;
}

主函数:

/*
	顺序表存储结构
	线性表的顺序表示指的是用一组地址连续的存储单元一次存储线性表的数据元素
	本程序用数组来实现
*/
#include "algorithm.h"							
#include "c.h"
#include "estimate.h"

int main (void) {
	SQLIST L;
	int e;
	int e0;
	Status i;
	int j;
	int k;

	//测试初始化函数
	i = initList(&L);
	printf("初始化L后:L.pElem=%u L.length=%d L.listsize=%d\n", L.pElem, L.length, L.listsize);		

	//.表示访问结构体成员
	//测试插入函数
	for (j=1; j<=5; j++)
	{
		i = listInsert(&L, 1, j);
	}
	printf("在L的表头依次插入1-5后:*L.pElem= ");
	for (j=1; j<=5; j++)
	{
		printf("%d ", L.pElem[j-1]);
	}
	printf("\n");

	printf("L.pElem=%u L.length=%d L.listsize=%d\n", L.pElem, L.length, L.listsize);

	//测试判空函数
	i = listEmpty(&L);																	
	printf("L是否空:i=%d(1:是 0:否)\n", i);

	//测试清空函数
	i = clearList(&L);
	i = listEmpty(&L);
	printf("L是否空:i=%d(1:是 0:否)\n", i);

	for (j=1; j<=10; j++)
	{
		listInsert(&L, 1, j);
	}
	printf("在L的表头依次插入1-10后:*L.pElem= ");
	for (j=1; j<=10; j++)
	{
		printf("%d ",L.pElem[j-1]);
	}
	printf("\n");
	printf("L.pElem=%u L.length=%d L.listsize=%d\n", L.pElem, L.length, L.listsize);
	listInsert(&L, 1, 0);
	printf("在L的表头插入0后:*L.pElem= ");
	for (j=1; j<=L.length; j++)
	{
		printf("%d ",L.pElem[j-1]);
	}
	printf("L.pElem=%u(有可能改变) L.length=%d(改变) L.listsize=%d(改变)\n", L.pElem, L.length, L.listsize);

	getElem(&L, 5, &e);
	printf("第5个元素的值为:%d\n", e);



	for (j=1; j<=10; j++)
	{
		getElem(&L, j, &e0);					//把第i个数据赋给e0
		i = priorElem(&L, e0, &e);				//求e0的前驱
		if (INFEASIBLE == i)
		{
			printf("元素%d无前驱\n", e0);		
		}
		else
		{
			printf("元素%d的前驱为:%d\n", e0, e);		
		}
	}

	for (j=L.length-1; j<=L.length; j++)
	{
		getElem(&L, j, &e0);
		i = nextElem(&L, e0, &e);
		if (INFEASIBLE == i)
		{
			printf("元素%d无后继\n", e0);
		}
		else 
		{
			printf("元素%d的后继为:%d\n", e0, e);		
		}
	}

	k = listLength(&L);
	for (j=k+1; j>=k; j--)
	{
		i = listDelete(&L, j, &e);
		if (ERROR == i)
		{
			printf("删除第%d个元素失败\n", j);
		}
		else
		{
			printf("删除的元素值为%d\n", e);		
		}
	}
	printf("依次输出L的元素:");
	listTraverse(&L);

	destroyList(&L);
	printf("销毁L后:L.pElem=%u L.length=%d L.listsize=%d\n", L.pElem, L.length, L.listsize);
	return 0;
}


运行结果:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值