線性列表的順序實現

一、線性列表的特點

(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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章