考研數據結構複習——線性表(順序結構)

線性表(順序結構)

/**
***@Title   :考研數據結構複習
***@Subject :線性表(順序結構)
***@Author  :lxfhahaha
***@language: C語言
***@Time    : 2018/9/21 19:09
*****/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define Inital_Size 50
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

typedef int Bool;
typedef int ElemType;
typedef int Status;

typedef struct { 
	ElemType *data;
	int length;  //已有數據長度
	int maxsize; //線性表空間長度
}List;

//操作結果:構造一個空的線性表list
Status InitList(List *list){
	list->data=(ElemType*)malloc(Inital_Size*sizeof(ElemType));
	if(!list->data){
		printf("System Error!\n");
		exit(0);	
	}
	list->maxsize=Inital_Size;
	list->length=0;
	return OK;
}

//初始條件:線性表list已存在
//操作結果:銷燬線性表list
Status DestroyList(List *list){
	if(!list->data){  //不存在
		return ERROR;
	}else{
		free(list->data);
		list->data=NULL;
		list->maxsize=0;
		list->length=0;
		return OK;	
	}
}

//初始條件:線性表list已存在
//操作結果:將list重置爲空表
Status ClearList(List *list){
	int i;
	if(!list->data){
		printf("Error!! Please inital first!!\n");
		return ERROR;
	}
	for(i=0;i<list->length;i++){
		list->data[i]=0;
	}
	list->length=0;
	return OK;	
}

//初始條件:線性表list已存在
//操作結果:若list爲空表,返回TRUE,即1
//          若list不是空表,返回FALSE,即0
//          若list不存在,報錯,退出程序
Bool ListEmpty(List list){
	if(!list.data){
		printf("Error!! Please inital first!!\n");
		exit(0);
	}
	return list.length==0 ? TRUE : FALSE ;
}

//初始條件:線性表list已存在
//操作結果:返回list中數據元素個數
int ListLength(List list){
	if(!list.data){
		printf("Error!! Please inital first!!\n");
		exit(0);
	}
	return list.length;
}

//初始條件:線性表list要已存在, 且1<=i<=ListLength(list)
//操作結果:用e返回list中弟i個數據元素的值
Status GetElem(List list,int i,ElemType *e){
	if(!list.data){
		printf("Error!! Please inital first!!\n");
		exit(0);
	}
	if(i>ListLength(list)||i<=0){
		printf("Error get ElemType %d\n",i);
		return ERROR;
	}
	*e=list.data[i-1];
	return OK;
}

//初始條件:線性表list已存在
//操作結果:返回list中第一個與e相等的數據元素的位序(1<=位序
//          號<=ListLength(list))。若這樣的數據元素不存在,則返回0
int ExistElem(List list,ElemType e){
	int i;
	if(!list.data){
		printf("Error!! Please inital first!!\n");
		exit(0);
	}
	for (i=0; i<list.length && list.data[i] != e ; i++ );
	return  i==list.length ? 0 : i+1 ;
}


//初始條件:線性表list已存在,compare()是數據元素判定函數
//操作結果:返回list中第一個與e滿足關係compare()的數據元素的位序(1<=位序
//          號<=ListLength(list))。若這樣的數據元素不存在,則返回0
int LocateElem(List list,ElemType e,Bool (*compare)(ElemType,ElemType)){
	int i;
	if(!list.data){
		printf("Error!! Please inital first!!\n");
		exit(0);
	}
	for (i=0; i<list.length && !(*compare)(list.data[i],e) ; i++ );
	return  i==list.length ? 0 : i+1 ;
}

//初始條件:線性表list已存在
//操作結果:若cur_e是list的數據元素,且不是第一個,則用pre_e返回
//          他的前驅,否則操作失敗,pre_e無定義
Status PriorElem(List list,ElemType cur_e,ElemType *pre_e){
	int itr;
	if(!list.data){
		printf("Error!! Please inital first!!\n");
		exit(0);
	}
	if((itr=ExistElem(list,cur_e)) && itr != 1){
		*pre_e=list.data[itr-2];
		return OK;
	}else{
		return ERROR;
	}
}

//初始條件:線性表list已存在
//操作結果:若cur_e是list的數據元素,且不是最後一個,則用next_e返回
//          他的後繼,否則操作失敗,next_e無定義
Status NextElem(List list,ElemType cur_e,ElemType *pre_e){
	int itr;
	if(!list.data){
		printf("Error!! Please inital first!!\n");
		exit(0);
	}
	itr=ExistElem(list,cur_e);
	if(itr !=0 && itr != list.length){
		*pre_e=list.data[itr];
		return OK;
	}else{
		return ERROR;
	}
}

//初始條件:線性表list要已存在,且1<=i<=ListLength(list)+1
//操作結果:在list中第i個位置之前插入新的數據元素e,list的length加一
Status ListInsert(List *list,int i,ElemType e){
	int itr;
	if(!list->data){
		printf("Error!! Please inital first!!\n");
		exit(0);
	}
	if((itr=ListLength(*list))<i-1||i<1){
		printf("Error insert ElemType in %d\n",i);
		return ERROR;
	}
	if(i>list->maxsize){
		ElemType *new_base=(ElemType*)realloc(list->data,(list->maxsize+Inital_Size)*sizeof(ElemType));
		if(!new_base){
			printf("Error Realloc, OverFlow!\n");
			exit(0);
		}
		list->data=new_base;
		list->maxsize+=Inital_Size;
	}
/********* 第一種  ***********/	
/*	while(itr>=i){
		list->data[itr]=list->data[itr-1];
		itr-=1;    
	}
	list->data[i-1]=e;
	list->length += 1;
*/
/********* 第二種  **********/
	ElemType *p,*q;
	p=&(list->data[i-1]); //要插入的地址
	for(q=&(list->data[list->length-1]);q>=p;q--)
		*(q+1)=*q;
	*p=e;
	list->length ++;
	return OK;
}

//初始條件:線性表list要已存在且非空,且1<=i<=ListLength(list)
//操作結果:刪除list中第i個數據元素,並用e返回其值,ist的length減一
Status ListDelete(List *list,int i,ElemType *e){
	int itr;
	if(!list->data){
		printf("Error!! Please inital first!!\n");
		exit(0);
	}
	
	if(!(itr=ListLength(*list))||i<1||i>itr){
		printf("Error delete ElemType in %d\n",i);
		return ERROR;
	}
	*e=list->data[i-1];
	while(itr>i){
		list->data[i-1]=list->data[i];
		i+=1;
	}
	list->length -= 1;
	return OK;
}

//初始條件:線性表list要已存在
//操作結果:依次對list的每個數據元素調用函數visit()。一旦visit()
//          失敗,則操作失敗
Status ListTraverse(List list,Status (*visit)(ElemType)){
	int itr;
	if(!list.data){
		printf("Error!! Please inital first!!\n");
		exit(0);
	}
	for(itr=0;itr<list.length;itr++){
		if(!(*visit)(list.data[itr]))
			return ERROR;
	}
	return OK;
}

//初始條件:線性表list要已存在
//操作結果:打印list
Status ListPrint(List list){
	int itr;
	if(!list.data){
		printf("Error!! Please inital first!!\n");
		exit(0);
	}
	printf("list_length: %d ; list_maxsize: %d \n",list.length,list.maxsize);
	printf("[");
	for(itr=0;itr<list.length;itr++){
		printf("%d",list.data[itr]);
		if(itr!=list.length-1)
			printf(",");
	}
	printf("]\n");
	return OK;
}

//初始條件:線性表la,lb,lc要已存在,且la,lb裏面的元素要單調不減
//操作結果:合併la,lb元素到lc,合併後的元素也單調不減
Status MergeList(List la,List lb,List *lc){
	int i=0,j=0;
	ElemType da,db;
	ElemType *pa,*pb,*pa_end,*pb_end,*pc;
	if(!la.data||!lb.data||!InitList(lc)){
		printf("Error!! Please inital first!!\n");
		exit(0);
	}
	pa=la.data;
	pb=lb.data;
	pa_end=&(la.data[la.length-1]);
	pb_end=&(lb.data[lb.length-1]);
	while(pa<=pa_end && pb<=pb_end){
		if(*pa<=*pb){
			ListInsert(lc, lc->length+1, *pa);
			pa++;
		}
		else{
			ListInsert(lc, lc->length+1, *pb);
			pb++;
		}
	}
	while(pa<=pa_end){
    	ListInsert(lc, lc->length+1, *pa);
		pa++;
	}
	while(pb<=pb_end){
		ListInsert(lc, lc->length+1, *pb);
		pb++;
	}	
	return OK;
}

//test1—>LocateElem—>compare
Bool Compare_test(ElemType A,ElemType B){
  return ( A==B ? TRUE : FALSE );
}

//test2—>ListTraverse—>vist
Status Visit_test(ElemType A){
  printf("HaHaHa,I'm %d.\n",A);
  return OK;
}

int main()
{
	List list;
	int i,j;
	ElemType a,b,c,d;
	InitList(&list);
	srand((int)time(0));		
	for(i=1;i<=10;i++)
		ListInsert(&list, i, (ElemType)rand()%100);
	ListPrint(list);
	for(j=0;j<50;j++){
		d=(ElemType)rand()%100;
		i=ExistElem(list, d); //存在這個元素,返回其位置
		if(i){
			GetElem(list, i, &a);   //獲得這個位置的元素保存爲a
			PriorElem(list, a, &b); //獲得這個位置的元素的前驅保存爲b
			NextElem(list, a, &c); //獲得這個位置的元素的後繼保存爲c
			printf("Random: %d ;Index: %d ;Exist: %d ;Prio: %d ;Next: %d \n",d,i,a,b,c);
		}
		i=a=b=c=d=0;
	}
	
	for(j=0;j<3;j++){
		d=rand()%list.length+1;
		ListDelete(&list, d, &a);
		printf("\ndelete list[%d] ( %d ) , after delete:\n",d-1,a);
		ListPrint(list);
	}
	
	putchar('\n');
	ListTraverse(list, Visit_test);
	putchar('\n');
	
	for(j=0;j<50;j++){
		d=(ElemType)rand()%100;
		i=LocateElem(list, d, Compare_test); //存在這個元素,返回其位置
		if(i){
			GetElem(list, i, &a);   //獲得這個位置的元素保存爲a
			PriorElem(list, a, &b); //獲得這個位置的元素的前驅保存爲b
			NextElem(list, a, &c); //獲得這個位置的元素的後繼保存爲c
			printf("Random: %d ;Index: %d ;Exist: %d ;Prio: %d ;Next: %d \n",d,i,a,b,c);
		}
		i=a=b=c=d=0;
	}
	DestroyList(&list);
	
	//test merge	
	List la,lb,lc;
	InitList(&la);
	InitList(&lb);
	
	putchar('\n');
	for(i=1;i<=10;i++)
		ListInsert(&la, i, (i==1?0:la.data[i-2])+(ElemType)rand()%10);
	ListPrint(la);
	putchar('\n');
	for(i=1;i<=8;i++)
		ListInsert(&lb, i, (i==1?0:lb.data[i-2])+(ElemType)rand()%10);
	ListPrint(lb);
	putchar('\n');
	MergeList(la,lb, &lc);
	ListPrint(lc);
	return 0;	
}

運行結果

———————————————————
從今天開始整理一些資料,全部開始重新手打。。要是有問題的,敬請斧正,thx。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章