顺序线性表是最常用最简单的一种数据结构。简而言之。一个线性表是 n 个数据元素的有限序列。
//3月28号,关于LocateElem 和 ListTraverse未写,还未搞懂两种函数
//的实质
//3月29号完工。
//3月31号补充扩大线性表。类似 A = A U B
//补充 合并两个线性表
/*Linear list :
**linear list has the only one data element called "the first"
**and the only one data element called "the last"
**every element has a previous expect the first one element
**every element has a subsequent expect the last one element
*/
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define INFEASIBLE -2
#define INIT_LIST_SIZE 100
#define INCREAMENTLIST 10
typedef int Status;
typedef int ElemType;
typedef struct{
ElemType *elem; //the linear list's basic address
int length; //the linear list's length
int listsize; //the linear list's size
}SqList;
//Initialize an empty linear list
Status InitList( SqList &L ){
//assign memory to linear list's elements
L.elem = (ElemType *) malloc (INIT_LIST_SIZE * sizeof(ElemType));
//if fail return ERROR
if( !L.elem )
return ERROR;
L.length = 0; //empty linear list's length is zero
L.listsize = INIT_LIST_SIZE; //initial linear list's size
return OK;
}
//Destroy linear list
Status DestroyList( SqList &L ){
//Initial condition : Linear list exist
if( !L.elem )
return ERROR;
free( L.elem );
L.elem = NULL;
L.length;
L.listsize = 0;
return OK;
}
//Clean linear list
Status CleanList( SqList &L ){
DestroyList( L );
L.length = 0;
return OK;
}
//If linear list is an empty list return TRUE otherwise return FALSE
Status ListEmpty( SqList L ){
if( L.length == 0 )
return TRUE;
else
return FALSE;
}
//Get the length of linear list
Status ListLength( SqList L ){
return L.length;
}
//Get the element
Status GetElem( SqList L, int i, ElemType &e ){
if( !L.elem )
return ERROR;
if( i < 1 || i > ListLength( L ) ) // i in range(ListLength(L))
return ERROR;
e = *(L.elem + i - 1);
return e;
}
Status LocateElem( SqList L, ElemType e,
Status compare( ElemType e1, ElemType e2)){
int i = 1;
ElemType *p = L.elem;
while( i <= ListLength(L) && !(*compare)( *p++, e ) )
++i;
if( i <= ListLength(L) )
return i;
else
return 0;
}
//return an element's previous element
Status PriorElem( SqList L, ElemType cur_e, ElemType &pre_e ){
//cur_e isn't the first element of the linear list
if( cur_e == *L.elem )
return ERROR;
ElemType *p = L.elem + 1;
int i = 2;
while( i < ListLength( L ) && *p != cur_e ){
p++;
i++;
}
if( i > ListLength(L) )
return INCREAMENTLIST;
else
pre_e = *--p; //error : pre_e = *(p--);
return OK;
}
//return an element's subsequent element
Status NextElem( SqList L, ElemType cur_e, ElemType &next_e ){
//cur_e isn't the last element of the linear list
if( cur_e == *(L.elem + ListLength(L) - 1) )
return ERROR;
ElemType *p = L.elem + 1;
int i = 2;
while( i < ListLength(L) && *p != cur_e ){
p++;
i++;
}
if( i > ListLength(L) )
return INFEASIBLE;
else
next_e = *++p;
return OK;
}
//Insert a new element e into i - 1
Status ListInsert( SqList &L, int i, ElemType e ){
if( i < 1 || i > ListLength(L) + 1 )
return ERROR;
if( ListLength(L) >= L.listsize ){
ElemType *newbase = (ElemType *) realloc (L.elem,
(L.listsize + INCREAMENTLIST) * sizeof(ElemType));
if( !newbase )
exit(OVERFLOW);
L.elem = newbase;
L.listsize += INCREAMENTLIST;
}
ElemType *q = (L.elem + i - 1);
for( ElemType *p = (L.elem + ListLength(L) - 1);
p >= q;
p-- ){
*(p + 1) = *p;
}
*q = e;
L.length++;
return OK;
}
//Delete element
Status ListDelete( SqList &L, int i, ElemType &e ){
if( !L.elem )
return ERROR;
if( i < 1 || i > ListLength(L) )
return ERROR;
ElemType *q = (L.elem + i - 1); //delete
e = *q;
ElemType *p = (L.elem + ListLength(L) - 1); //the last element
for( ++q; q <= p; q++ ){
*(q - 1) = *q;
}
L.length--;
return OK;
}
/*扩大线性表 La
** 类似数学里的 A = A U B
**将 B 中不属于 A 的元素插入 A 中
*/
void UNION( SqList &La, SqList Lb ){
Status equal( ElemType e1, ElemType e2 );
int La_len = ListLength(La);
int Lb_len = ListLength(Lb);
int i;
ElemType get_e;
for( i = 1; i <= Lb_len; i++ ){
GetElem( Lb, i ,get_e );
if( !LocateElem( La, get_e, equal ) )
ListInsert( La, ++La_len, get_e);
}
}
Status equal( ElemType e1, ElemType e2 ){
if( e1 == e2 )
return TRUE;
else
return FALSE;
}
//merge two linear lists
void MergeList( SqList La, SqList Lb, SqList &Lc ){
InitList(Lc);
int La_len = ListLength(La);
int Lb_len = ListLength(Lb);
int i = 1, j = 1;
int k = 0;
ElemType get_e1, get_e2;
while( i <= La_len && j <= Lb_len ){
GetElem(La, i, get_e1);
GetElem(Lb, j, get_e2);
if( get_e1 < get_e2 ){
ListInsert(Lc,++k,get_e1);
i++;
}
else{
ListInsert(Lc,++k,get_e2);
j++;
}
}
while( i <= La_len ){
GetElem(La,i,get_e1);
ListInsert(Lc,++k,get_e1);
i++;
}
while( j <= Lb_len ){
GetElem(La,j,get_e2);
ListInsert(Lc,++k,get_e2);
j++;
}
}
下面是顺序线性表的实现:
#include <stdio.h>
#include "linear_list.h"
int main(void)
{
SqList L; //declare a linear list L
//Create an empty linear list L
InitList( L );
//Check the linear list L
printf("L.elem = %u L.length = %d L.listsize = %d\n",
L.elem, L.length, L.listsize);
//Insert 5 element into linear list L
for( int init_i = 1;init_i <= 5; init_i++ ){
ListInsert( L, 1 , init_i );
}
//output all elements in linear list L
printf("The linear list's elements: ");
for( int print_j = 1; print_j <= ListLength(L); print_j++ ){
printf("%d ",L.elem[print_j - 1]);
}
putchar('\n');
//Check again
printf("L.elem = %u L.length = %d L.listsize = %d\n",
L.elem, L.length, L.listsize);
//Insert 5 element into linear list L
for( int insert_i = 6; insert_i <= 10; insert_i++ ){
ListInsert( L, 5, insert_i );
}
printf("The new linear list's elements:");
//output all element in linear list L
for( int print_j = 1; print_j <= ListLength(L); print_j++ ){
printf("%d ",L.elem[print_j-1]);
}
putchar('\n');
//delete a element
ElemType del_e;
ListDelete( L, 1, del_e );
//output the element whick was deleted
printf("The %d has been deleted.\n",del_e);
//output all element in linear list L
printf("The new linear list's elements:");
for( int print_j = 1; print_j <= ListLength(L); print_j++ ){
printf("%d ",L.elem[print_j - 1]);
}
putchar('\n');
//Get an element you want
ElemType get_e;
GetElem( L, 2, get_e );
printf("You want %d\n",get_e);
//Linear list's length
ListLength(L);
printf("The linear list's length%d\n",L.length);
//Show the previous and subsequent
for( int print_j = 1; print_j <= ListLength(L); print_j++ ){
printf("%d ",L.elem[print_j - 1]);
}
putchar('\n');
printf("Get the second element.\n");
ElemType pre_e;
PriorElem( L, GetElem(L,2,get_e), pre_e );
printf("The previous element %d \n",pre_e);
printf("Get the fifth element.\n");
ElemType next_e;
NextElem( L, GetElem(L,5,get_e), next_e );
printf("The next element %d \n",next_e);
//Destroy linear list
DestroyList(L);
CleanList(L);
return 0;
}
以下是扩大线性表的测试:
#include <stdio.h>
#include "linear_list.h"
int main(void)
{
SqList La, Lb;
//Initialize La and Lb
InitList( La );
InitList( Lb );
//Insert elements into La and Lb
for( int i = 1; i <= 5; i++ )
ListInsert( La, 1, i );
for( int j = 3; j <= 7; j++ )
ListInsert( Lb, 1, j );
//output La and Lb
ElemType get_e;
for( int i = 1; i <= ListLength(La); i++ )
printf("%d ",GetElem(La,i,get_e));
putchar('\n');
for( int j = 1; j <= ListLength(Lb); j++ )
printf("%d ",GetElem(Lb,j,get_e));
putchar('\n');
//union La and Lb
UNION( La, Lb );
for( int i = 1; i <= ListLength(La); i++ )
printf("%d ",GetElem(La,i,get_e));
putchar('\n');
return 0;
}
合并两个线性表的测试:
#include <stdio.h>
#include "linear_list.h"
int main(void)
{
SqList La, Lb;
SqList Lc;
//Initialize La and Lb
InitList(La);
InitList(Lb);
//Insert elements into La and Lb
int i = 1;
int j = 1;
ElemType a, b;
puts("Please enter the numbers to insert into La: ");
while( i <= 4 ){
scanf("%d",&a);
ListInsert(La,i,a);
i++;
}
for( int i =1; i <= ListLength(La); i++ ){
ElemType get_a;
printf("%d ",GetElem(La,i,get_a));
}
putchar('\n');
puts("Please enter the numbers to insert into Lb: ");
while( j <= 7 ){
scanf("%d",&b);
ListInsert(Lb,j,b);
j++;
}
for( int j = 1; j <= ListLength(Lb); j++ ){
ElemType get_b;
printf("%d ",GetElem(Lb,j,get_b));
}
putchar('\n');
MergeList(La,Lb,Lc);
ElemType get_e;
printf("The Lc : ");
for( int i = 1; i <= ListLength(Lc); i++ ){
printf("%d ",GetElem(Lc,i,get_e));
}
return 0;
}