1. 程式人生 > >資料結構——線性表的順序表示和實現(c語言)

資料結構——線性表的順序表示和實現(c語言)

PS:資料結構(C語言版)——清華大學出版社, 2.1節程式碼實現
#include <stdio.h>
#include <stdlib.h>

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1  
#define OVERFLOW -2
#define LIST_INIT_SIZE 100   //順序表初始分配空間
#define LISTINCREMENT 10   //順序表儲存空間分配增量

//Status是函式的型別,其值是函式結果狀態碼
typedef int Status;
typedef int ElemType;   //順序表儲存元素型別, 考慮到可移植性, 若改變儲存型別, 只需修改這一處,比較方便
typedef struct 
{
	ElemType *elem;   //儲存空間地址
	int length;   //當前長度
	int listsize;   //當前分配的儲存容量(以sizeof(ElemType)為單位)
}SqList;

void Init_Sq(SqList *L);
Status Insert_Sq(SqList *L, int i, ElemType e);
Status Destroy_Sq(SqList *L);
Status Delete_List(SqList *L, int i);
void Travse_Sq(SqList *L);
ElemType Next_Elem(SqList *L, int cur_elem);
ElemType Prior_Elem(SqList *L, int cur_elem);
ElemType GetElem(SqList *L, int i);
int LocateElem_Sq(SqList *L, ElemType e);
Status compare(ElemType e1, ElemType e2);
int ListLength(SqList *L);
void union_Sq(SqList *La, SqList *Lb);
void Merge_Sq(SqList *La, SqList *Lb, SqList *Lc);

void main()
{	

	/*SqList L;
	int i;
	Init_Sq(&L);
	if(	Insert_Sq(&L, 1, 4))
	{
		printf("The element is %d\n", GetElem(&L, 1));
	}
	if(	Insert_Sq(&L, 2, 5))
	{
		printf("The element is %d\n", GetElem(&L, 2));
	}
	if(	Insert_Sq(&L, 3, 6))
	{
		printf("The element is %d\n", GetElem(&L, 3));
	}
	if(	Insert_Sq(&L, 4, 8))
	{
		printf("The element is %d\n", GetElem(&L, 4));
	}
	if(	Insert_Sq(&L, 5, 18))
	{
		printf("The element is %d\n", GetElem(&L, 5));
	}
	Travse_Sq(&L);
	printf("Current number:  ");
	scanf("%d", &i);
	printf("The prior of No.%d is %d\n", i, Prior_Elem(&L, i));

	
	if(Delete_List(&L,1))
	{
		printf("After delete:\n");
		Travse_Sq(&L);
	}
	*/

	SqList La;
	SqList Lb;
	SqList Lc;

	Init_Sq(&La);
	Init_Sq(&Lb);

	if(	Insert_Sq(&La, 1, 4))
	{
		printf("The element in La is %d\n", GetElem(&La, 1));
	}
	if(	Insert_Sq(&La, 2, 5))
	{
		printf("The element in La is %d\n", GetElem(&La, 2));
	}
	if(	Insert_Sq(&La, 3, 6))
	{
		printf("The element in La is %d\n", GetElem(&La, 3));
	}
	if(	Insert_Sq(&La, 4, 8))
	{
		printf("The element in La is %d\n", GetElem(&La, 4));
	}
	if(	Insert_Sq(&La, 5, 18))
	{
		printf("The element in La is %d\n", GetElem(&La, 5));
	}

	printf("\n");
	if(	Insert_Sq(&Lb, 1, 4))
	{
		printf("The element in Lb is %d\n", GetElem(&Lb, 1));
	}
	if(	Insert_Sq(&Lb, 2, 15))
	{
		printf("The element in Lb is %d\n", GetElem(&Lb, 2));
	}
	printf("\n");

	//union_Sq(&La, &Lb);   

//	printf("After unite La and Lb:\n");
//	Travse_Sq(&La);
	Merge_Sq(&La, &Lb, &Lc);
	printf("After merge La and Lb:\n");
	Travse_Sq(&Lc);
	Destroy_Sq(&La);
	Destroy_Sq(&Lb);
	Destroy_Sq(&Lc);
}

void Init_Sq(SqList *L)
{
	L->elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));
	if(L->elem == NULL)
	{
		printf("Memory allocation is error!");
		exit(1);   //0表示正常退出,非零表示異常退出
	}
	L->length = 0;
	L->listsize = LIST_INIT_SIZE;
}

//在第i個位置插入元素e
Status Insert_Sq(SqList *L, int i, ElemType e)
{
	ElemType *newbase;   //指向新增順序表後的起始位置
	ElemType *p;
	ElemType *q;

	if(i < 1 || i > L->length +  1)
	{
		printf("The location that inserted is illegal!\n");
		return TRUE;
	}

	if(!(L->length < L->listsize))   //如果順序表滿了就擴充
		newbase = (ElemType *)realloc(&L->elem, (L->length + LISTINCREMENT) * sizeof(ElemType));

	p = &L->elem[i-1];

	for(q = &L->elem[L->length - 1]; p <= q; q--)
	{
		*(q + 1) = *q;
	}

	*p = e;
	L->length ++;
	return TRUE;
}

//銷燬順序表
Status Destroy_Sq(SqList *L)
{
	if(L->length < 1)
		return FALSE;
	free(L->elem);
	L->elem = NULL;
	return TRUE;
}

//刪除順序表中指定元素
Status Delete_List(SqList *L, int i)
{
	ElemType *p;
	int j;

	if(i < 1 && i > L->length)
	{
		printf("The site that store element is not exist!\n");
		return FALSE;
	}

	p = &L->elem[i - 1];   //初始使p指向將要刪除的位置

	for(j = i - 1; j < L->length - 1; j++)
	{
		*p = *(p+1);
		p++;
	}
	L->length --;
	return TRUE;
}

//遍歷順序表
void Travse_Sq(SqList *L)
{
	int i;
	if(L->length == 0)
	{
		printf("The sequence list is empty!\n");
	}
	else
		for(i = 0; i < L->length; i++)
			printf("The No.%d is %d.\n", i, L->elem[i]);
}

//返回第i個數據
ElemType GetElem(SqList *L, int i)
{
	if(i < 1 || i > L->length)
		return ERROR;
	return L->elem[i - 1];
}

//返回第cur_elem個元素的直接前驅
ElemType Prior_Elem(SqList *L, int cur_elem)
{
	if(cur_elem == 1)
		return ERROR;
	else
		return L->elem[cur_elem - 2];
}

//返回第cur_elem個元素的直接後繼
ElemType Next_Elem(SqList *L, int cur_elem)
{
	if(cur_elem == (L->length - 1))
		return FALSE;
	else
		return L->elem[cur_elem];
}

//記錄線性表的長度
int ListLength(SqList *L)
{
	if(L->length == 0)
	{
		printf("The sequence list is empty!\n");
		return 0;
	}
	else 
		return L->length;

}

//線性表A和B作並集操作
void union_Sq(SqList *La, SqList *Lb)
{
	//將所有線上性表Lb中但不在La中的資料元素插入到La中
	int La_len, Lb_len;
	int i;
	int Lb_cur_elem;   //記錄Lb中取出的元素

	La_len = ListLength(La);
	Lb_len = ListLength(Lb);

	//注意,取的是第i個元素,是從人們熟悉的1開始計數
	//GetElem()函式中會做減1處理(計算機的計數方式)
	for(i = 1; i <= Lb_len; i++)
	{
		Lb_cur_elem = GetElem(Lb, i);
		if(!LocateElem_Sq(La, Lb_cur_elem))
			Insert_Sq(La, ++La_len, Lb_cur_elem);
	}
}

Status compare(ElemType e1, ElemType e2)
{
	if(e1 == e2)
		return TRUE;
	else 
		return FALSE;
}

//在順序線性表L中查詢第一個值與e滿足compare()的元素的位序
//若找到,則返回其在L中的位序,否則返回0
int LocateElem_Sq(SqList *L, ElemType e)
{
	int i;
	ElemType *p;
	i = 1;   //i的初值為第一個元素的位序
	p = L->elem;   //p的初值為第1個元素的儲存位置
	while(i <= L->length && (e != *p++))
		i++;
	if(i <= L->length)
		return i;
	else 
		return 0;
}

//已知順序線性表La,和Lb的元素按值非減排列
//歸併La和Lb得到新的順序線性表Lc,Lc的元素也是按值非減排列
void Merge_Sq(SqList *La, SqList *Lb, SqList *Lc)
{
	ElemType *pa;
	ElemType *pb;
	ElemType *pc;
	ElemType *pa_last;
	ElemType *pb_last;

	//給Lc的elem元素分配空間
	Lc->elem = (ElemType *)malloc((La->length + Lb->length) * sizeof(ElemType));
	if(!Lc->elem)
	{
		printf("Error!\n");
		exit(1);
	}

	pa = La->elem;   //pa指向La的第一個元素
	pb = Lb->elem;	 //pb指向Lb的第一個元素		
	pc = Lc->elem;   //pc指向Lc的首地址
	Lc->length = La->length + Lb->length;
	
	pa_last = &La->elem[La->length - 1];   //指向La的最後一個元素(La中的最大的元素)
	pb_last = &Lb->elem[Lb->length - 1];   //指向Lb的最後一個元素(Lb中的最大的元素)

	while(pa <= pa_last && pb <= pb_last)   //實現歸併
	{
		if(*pa <= *pb)
		{
			*pc++ = *pa++;
		}
		else
			*pc++ = *pb++;
	}
	while(pa <= pa_last)
		*pc++ = *pa++;
	while(pb <= pb_last)
		*pc++ = *pb++;
}