线性列表的顺序实现

一、线性列表的特点

(1)存在唯一的一个被称作“第一个”的数据元素。
(2)存在唯一的一个被称作“最后一个”的数据元素。
(3)除第一个外,集合中的每一个数据元素均只有一个前驱。
(4)除最后一个外,集合中每一个数据元素均只有一个后续。

二、线性表的顺序实现

  线性表的顺序实现是指用一组地址连续的存储单元依次存储线性表的数据元素。
元素的存储位置满足以下关系:
    LOC(ai+1) = LOC(ai) + l;

三、具体实现

*注意第一个元素对应数组下标0

#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
//定义常量
#define LIST_INIT_SIZE 100
#define LISTINCRASE 10
#define OK 1
#define ERROR -1
#define OVERFLOW -1

//定义数据类型,方便改变
typedef int ElemType;

typedef int Status;

typedef struct{
	ElemType *elem;
	int      length;
	int      listSize;
}SqList;


Status initList_Sq(SqList &L);
Status listInsert_Sq(SqList &L,int i ,ElemType e);
Status listDelete_Sq(SqList &L,int i,ElemType &e);
Status compare(ElemType e1, ElemType e2);
int locateElem_Sq(SqList L,ElemType e);
Status destory(SqList &L);
Status clearList(SqList &L);
Status listEmpty(SqList L);
int listLength(SqList L);
Status getElem(SqList L,int i,ElemType &e);
Status priorElem(SqList L,ElemType cur_e,ElemType &pre_e);
Status nextElem(SqList L,ElemType cur_e,ElemType &next_e);
void travse_Sq(SqList L);
void union_Sq(SqList &La,SqList Lb);

//初始化线性表L,成功返回true,0-length个元素,0号使用
Status initList_Sq(SqList &L){

	L.elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));
	if(!L.elem)	return OVERFLOW;
	L.length   = 0;
	L.listSize = LIST_INIT_SIZE;
	return OK;
}

//向线性列表中第i个位置之前插入元素e,i到n依次向后移动,1 <= i <= n
Status listInsert_Sq(SqList &L,int i ,ElemType e){

	if(i < 1 || (i > L.length + 1) || L.elem == NULL) return ERROR;//检测位置i的合法性

	if(L.length >= L.listSize){//空间位置已满,扩容
		ElemType *newBase = NULL;
		newBase = (ElemType*)realloc(L.elem,(L.listSize + LISTINCRASE)*sizeof(ElemType));
		if(!newBase)	return OVERFLOW;
		L.elem = newBase;
		L.listSize = L.listSize + LISTINCRASE;
	}

	ElemType *q = NULL;
	ElemType *p = NULL;

	q = &(L.elem[i - 1]);//获得插入位置
	for(p = &L.elem[L.length - 1]; p >= q;--p)//数组指针的比较
		*(p + 1) = *p;
	*q = e;	//插入元素
	L.length++;
	return OK;
}

//	删除第i个元素,i+1到n的元素向前移动,1 <= i <= n
Status listDelete_Sq(SqList &L,int i,ElemType &e){

	if(i < 1 || (i > L.length) || L.elem == NULL) return ERROR;
	ElemType *q = NULL;
	ElemType *p = NULL;
	
	p = &L.elem[i - 1];//被删除元素位置
	e = *p;	//保存被删除元素
	q = &L.elem[L.length - 1];//list最后一个元素位置
	for(++p;p <= q;++p)//依次往前移动
		*(p - 1) = *p;
	L.length--;
	return OK;
}

//比较两个元素是否相等
Status compare(ElemType e1, ElemType e2){
	if(e1 == e2)
		return true;
	else 
		return false;
}

//查找顺序表list中存在的第一个和e相同的元素的位序,找不到返回ERROR
int locateElem_Sq(SqList L,ElemType e){
	int i = 1;
	ElemType *p = L.elem;
	while(i <= L.length && !(compare(e,*p++))) ++i;
	if(i <= L.length)
		return i - 1;
	else 
		return ERROR;
}

//若线性表L已经存在,则销毁
Status destory(SqList &L){
	
	if(L.elem != NULL){
		free(L.elem);
		L.elem = NULL;
	}else{
		return ERROR;
	}
	return OK;
}

//将线性表L重置为空表
Status clearList(SqList &L){

	if(L.length < 1 || L.elem == NULL)	return ERROR;
	memset(L.elem,0,L.length);
	L.length = 0;
	return OK;
}

//若线性表list为空,则返回true
Status listEmpty(SqList L){

	if(L.length == 0)	
		return true;
	else
		return false;
}

//返回线性表list的元素个数
int listLength(SqList L){
	
	return L.length;
}

//返回线性表中第i个元素的值
Status getElem(SqList L,int i,ElemType &e){

	if(i < 1 && (i > L.length) || L.elem == NULL)	return ERROR;
	if(L.elem == NULL) return ERROR;

	e = L.elem[i - 1];
	return OK;
}

//返回线性表当前节点的前驱,当前节点不能为第一个节点
Status priorElem(SqList L,ElemType cur_e,ElemType &pre_e){

	if(L.length < 1 || L.elem == NULL)	return ERROR;
	int ret  = locateElem_Sq(L,cur_e);
	if(ret  == 0 || ret == ERROR)//找不到或时第一个(i = 0)
		return ERROR;
	else{
		pre_e = L.elem[ret - 1];
		return OK;
	}
}

//返回线性表当前节点的后续,当前节点不能为最后一个节点
Status nextElem(SqList L,ElemType cur_e,ElemType &next_e){

	if(L.length < 1 || L.elem == NULL)	return ERROR;
	int ret  = locateElem_Sq(L,cur_e);
	if(ret  == ERROR || ret == L.length - 1)
		return ERROR;
	else{
		next_e = L.elem[ret + 1];
		return OK;
	}
}
//遍历顺序表
void travse_Sq(SqList L)
{
	if(L.elem == NULL || L.length < 1) return;

	for(int i = 0; i < L.length; i++)
			printf("%d ", L.elem[i]);
	printf("\n");
}

//线性列表La和Lb表示两个集合,求A = A U B,集合合并.算法复杂度:O(listLength(La)) * O(listLength(Lb))
void union_Sq(SqList &La,SqList Lb){

	if(La.length < 1 || Lb.length < 1) return;
	if(La.elem == NULL || Lb.elem == NULL) return;

	int la_len = listLength(La);
	int lb_len = listLength(Lb);

	for(int i = 0;i < lb_len;i++){
		ElemType e = Lb.elem[i];
		if(locateElem_Sq(La,e) == ERROR){
			listInsert_Sq(La,la_len++,e);
		}
	}
	//travse_Sq(La);
}
//将两个非递减线性列表相加,算法复杂度:O(listLength(La)) + O(listLength(Lb))
void mergeList(SqList La,SqList Lb,SqList &Lc){

	if(La.length < 1 || Lb.length < 1)	return ;
	if(La.elem == NULL || Lb.elem == NULL) return;

	int la_len = listLength(La);
	int lb_len = listLength(Lb);

	int i , j;
	i = j = 0;//从下标0开始取值
	int k = 1;//从第k个开始插入,1 <= k <= length

	while((i < la_len) && (j < lb_len)){
		
		if(La.elem[i] <= Lb.elem[j]){
			listInsert_Sq(Lc,k,La.elem[i]);//注意是从第k(i = k - 1)个开始插入
			i++;
		}else{
			listInsert_Sq(Lc,k,Lb.elem[j]);
			j++;
		}
		k++;
	}
	
	while(i < la_len){
		listInsert_Sq(Lc,k,La.elem[i]);
		k++;
		i++;
	}
	while(j < lb_len){

		listInsert_Sq(Lc,k,Lb.elem[j]);
		k++;
		j++;
	}
}
int main(){
	/*
	//插入
	SqList L;
	int ret = initList_Sq(L);
	if(!ret){
		printf("init error!\n");
		system("pause");
	}

	listInsert_Sq(L,1,3);
	listInsert_Sq(L,2,5);
	listInsert_Sq(L,3,7);
	listInsert_Sq(L,4,23);
	listInsert_Sq(L,5,55);

	travse_Sq(L);

	//删除
	ElemType e;
	ret = listDelete_Sq(L,2,e);
	if(ret)
		printf("delete success:%d\n",e);
	travse_Sq(L);

	//查找
	e = 23;
	ret = locateElem_Sq(L,e);
	if(ret)
		printf("find e = %d \n",e);
	else
		printf("not find e = %d \n",e);
	*/
	//应用实例
	SqList La,Lb,Lc;
	initList_Sq(La);
	initList_Sq(Lb);
	initList_Sq(Lc);

	printf("La:\n");
	listInsert_Sq(La,1,3);
	listInsert_Sq(La,2,5);
	listInsert_Sq(La,3,7);
	listInsert_Sq(La,4,12);
	listInsert_Sq(La,5,15);
	travse_Sq(La);

	printf("Lb:\n");
	listInsert_Sq(Lb,1,2);
	listInsert_Sq(Lb,2,7);
	listInsert_Sq(Lb,3,23);
	listInsert_Sq(Lb,4,55);
	travse_Sq(Lb);

	printf("A + B:\n");
	mergeList(La,Lb,Lc);
	travse_Sq(Lc);

	
	union_Sq(La,Lb);

	printf("A U B:\n");
	travse_Sq(La);
	getchar();
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章