1. 程式人生 > >線性表順序儲存學習

線性表順序儲存學習


線性表的順序儲存結構:

定義:用一段地址連續的儲存單元一次儲存線性表的資料元素。


/*線性表儲存的相應程式碼:
1.結構程式碼
2.初始化線性表
3.獲得元素操作
4.插入操作
5.刪除操作
6.判斷線性表是否為空
7.線性表清空
8.線性表中元素e首次出現位置
9.遍歷線性表:依次對L的每個資料元素輸出
10.將所有的線上性表Lb中,但不在La的資料元素插入La
*/
#include<stdio.h>

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 儲存空間初始分配量 */

typedef int Status;          /* Status是函式的型別,其值是函式結果狀態程式碼,如OK等 */
typedef int ElemType;        /* ElemType型別根據實際情況而定,這裡假設為int */

/* 1.線性表的順序儲存的結構程式碼 */
typedef struct
{
	ElemType data[MAXSIZE]; /* 陣列儲存資料元素,最大值為MAXSIZE */
	int length;             /* 線性表當前長度 */
}SqList;

/* 2.初始化線性表 */
Status InitList(SqList *L)
{
	L->length = 0;
	return OK;
}

/* 3.獲得元素操作 */
/* 初始條件:順序線性表L已存在,1≤i≤ListLength(L) */
/* 操作結果:用e返回L中第i個數據元素的值,注意i是指位置,第1個位置的陣列是從0開始 */
Status GetElem(SqList L,int i,ElemType *e)
{
	if(L.length == 0 || i<1 || i> L.length)
		return ERROR;
	*e = L.data[i-1];
	return OK;
}

/* 4.插入操作 */
/* 如果線性表已滿,無法插入,丟擲異常;如果插入位置不合理,丟擲異常;
從最後一個位置向前便利到第i個位置,分別向後移動一個位置;
將要插入的元素填入位置i處;
表長加1;
*/
Status ListInsert(SqList *L,int i,ElemType e)
{
	int k;
	if(L->length == MAXSIZE)
		return ERROR;
	if(i<1 || i> L->length+1)/* 當i比第一位置小或者比最後一位置後一位置還要大時 */
		return ERROR;
	if( i <= L->length)  /* 若插入資料位置不在表尾,需進行相應的後移操作 ;在表尾則可以直接插入末端*/
	{
		for(k = L->length-1; k >= i-1;k--)
			L->data[k+1] = L->data[k];
	}
    L->data[i-1] = e;   
	L->length++;
	return OK;
}

/* 5.刪除操作 */
/* 如果線性表為空,丟擲異常;如果刪除位置不合理,丟擲異常;
從刪除元素位置開始遍歷到最後一個元素位置,分別向前移動一個位置;
表長減1;
*/
Status ListDelete(SqList *L,int i,ElemType *e)
{
	int k;
	if(L->length == 0)
		return ERROR;
	if(i<1 || i> L->length)/* 當i比第一位置小或者比最後一位置後一位置還要大時 */
		return ERROR;
	*e = L->data[i-1];
	if( i < L->length)  /* 若刪除資料位置不在表尾,需進行相應的後移操作 ;在表尾則可以直接刪除*/
	{
		for(k = i; k <= L->length-1;k++)
			L->data[k-1] = L->data[k];
	} 
	L->length--;
	return OK;
}

/* 6.判斷線性表是否為空 ,空返回1,非空返回0*/
Status ListEmpty (SqList L)
{
	if ( L.length == 0 )
		return TRUE;
	else
		return FALSE;
}
/* 7.線性表清空*/
Status ClearList(SqList *L)
{
	L->length = 0;
	return OK;
}

/* 8.線性表中元素e首次出現位置*/
int LocateElem(SqList L,ElemType e)
{
	int i;
	if (L.length == 0 )
		return 0;
	for( i = 0; i < L.length; i++ )
		if( L.data[i] == e)
			break;
	if(i == L.length)
		return 0;
	return i+1;

}

/* 9.遍歷線性表:依次對L的每個資料元素輸出 */
Status ListTraverse(SqList L)
{
	int i;
    for(i=0;i<L.length;i++)
            printf("%d ",L.data[i]);
    printf("\n");
    return OK;
}

/* 10.將所有的線上性表Lb中,但不在La的資料元素插入La */
void unionL(SqList *La,SqList Lb)
{
	int La_len,Lb_len,i;
	ElemType e;           /*宣告La與Lb相同的資料元素 */
	La_len = La->length;
	Lb_len = Lb.length;
	for (i=1;i<=Lb_len;i++)
	{
		GetElem(Lb,i,&e);
		if (!LocateElem(*La,e))
			ListInsert(La,++La_len,e);
	}
}

int main()
{
        
    SqList L,Lb;
    ElemType e;
    Status i;
    int j,k;
    i=InitList(&L);
    printf("初始化L後:L.length=%d\n",L.length); 
	i=ListEmpty(L);
    printf("L是否空:i=%d(1:是 0:否)\n\n",i);

	for(j=1;j<=5;j++)
		i=ListInsert(&L,1,j);
	printf("在L的表頭依次插入1~5後:L.data=");
	ListTraverse(L); 
	i=ListEmpty(L);
    printf("L是否空:i=%d(1:是 0:否)\n\n",i);

	ListInsert(&L,1,0);
    printf("在L的表頭插入0後:L.data=");
    ListTraverse(L); 
    printf("L.length=%d \n\n",L.length);

	GetElem(L,5,&e);
    printf("第5個元素的值為:%d\n\n",e);

    for(j=3;j<=6;j++)
    {
            k=LocateElem(L,j);
            if(k)
                    printf("第%d個元素的值為%d\n",k,j);
            else
                    printf("沒有值為%d的元素\n",j);
    }
    printf("\n");

	k=L.length; /* k為表長 */
    for(j=k+1;j>=(k-1);j--)
    {
            i=ListDelete(&L,j,&e); /* 刪除第j個數據 */
            if(i==ERROR)
                    printf("刪除第%d個數據失敗\n",j);
            else
                    printf("刪除第%d個的元素值為:%d\n",j,e);
    }
    printf("依次輸出L的元素:");
    ListTraverse(L); 
	printf("\n");

	//構造一個有10個數的Lb
	//SqList Lb;
    i=InitList(&Lb);
    for(j=1;j<=10;j++)
            i=ListInsert(&Lb,1,j);
	unionL(&L,Lb);
	printf("依次輸出合併後L的元素:");
    ListTraverse(L); 
	printf("\n");

	i=ClearList(&L);
    printf("清空L後:L.length=%d\n",L.length);
    i=ListEmpty(L);
    printf("L是否空:i=%d(1:是 0:否)\n\n",i);
}