線性表

線性表
數據之間爲線性關係,數據元素“一個接一個的排列”
在一個線性表中數據元素的類型必須是相同的。
一般只是存儲查詢數據就用順序表,如果更改數據頻繁就用鏈式表
1.順序表
定義:
typedef struct /* 定義順序表 */
{
ElemType list [MaxSize];
int size;
}SequenceList;
SequemceList L; /* 定義順序表變量L */

操作:
①順序表的初始化
void ListInitialize()
{
L->size=0;
}
②求順序表的長度
int ListLength()
{
return L.size;
}
③插入
平均移動次數 n/2
時間複雜度O(n)
int ListInsert(SequenceList * L(順序表),int i(i 位置),ElemType x(要插入的元素))
{
int j;
if ( L->size >= MaxSize )
{
printf("順序表已滿無法插入!\n");
return 0;
}
else if ( i < 0 || i > L->size )
{
printf("參數i不合法!\n");
return 0;
}
else
{
for (j=L->size ; j>i ; j--)
L->list [ j ] = L->list [ j-1 ]; /* i位置後面的所有元素後移 */
L->list [ i ] = x; /* 插入 */
L->size ++ ; /* 表長+1 */
return 1;
}
}
④刪除
平均移動次數 (n-1)/2
時間複雜度 O(n)
int ListDelete ( SequenceList *L; int i; ElemType *x)
{
int j;
if (L->size <= 0)
{
printf("順序表已空無數據元素可刪");
return 0;
}
else if (i < 0 || i > L->size-1)
{
printf("參數 i 不合法");
return 0;
}
else
{
*x = L->list[ i ]; /* 用x存儲被刪除的元素 */
for (j=i +1; j <= L->size-1; j++)
L->size[ j-1 ] = L->list [ j ]; /* 元素前移 */
L->size --; /* 表長 -1 */
return 1;
}
}
⑤取元素
時間複雜度 O(1)
int ListGet ( SequenceList *L; int i; ElemType *x)
{
if ( i < 0 || i > L.size-1)
{
printf("參數i不合法!\n");
return 0;
}
else
{
*x=L.list [ i ];
return 1;
}
}

2.鏈式表
單鏈表
data
next
結點
不帶頭結點
head(頭指針) -> 首元結點(a0和指針域) -> (a1和指針域) -> ……(an和Null)
帶頭結點
頭結點(放額外信息 無數據) -> (a0和指針域) -> (a1和指針域) -> ……(an-1和Null)
定義:
typedef struct SingleNode
{
ElemType data;
struct SingleNode *next;
}SingleLinkedList, *LinkList;
操作:
時間複雜度均爲 O(n)
①初始化
void ListInitialize (SingleLinkedList * * head)
{
if ( (* head = (SingleLinkedList *) malloc (sizeof (SingleLinkedList) ) ) ==NULL) exit (1);
/* 如果有內存空間,申請頭結點空間並使頭指針head指向頭結點 */
(*head) -> next = NULL;
}
②求長度(長度不包括頭結點)
int ListLength (SingleLinkedList * head)
{
SingleLinkedList *p = head; /* p指向頭結點 */
int size = 0; /* size初始爲0 */
while (p -> next != NULL)
{
p = p -> next;
size ++;
}
return size;
}
③取元素
int ListGet (SingleLinkedList * head, int i(要取的元素位置), ElemType *x(存放要取的元素))
{
SingleLinkedList *p;
int j;
p = head; /* p指向頭結點 */
j = -1;
while (p -> next != NULL && j<i)
{
p = p -> next;
j ++ ;
}
if (j != i)
{
printf ("取元素位置參數錯誤!");
return 0;
}
*x = p -> data;
return 1;
}
④插入
int ListInsert (SingleLinkedList * head, int i, ElemType x )
{
SingleLinkedList *p, *q; /* q爲新結點 */
int j;
p = head; /* p指向頭結點 */
j = -1;
while (p -> next != NULL && j<i-1)
{
p = p -> next;
j ++;
}
if ( j != i-1)
{
printf (“插入位置參數錯!”);
return 0;
}
if ( (q = (SingleLinkedList * ) malloc (sizeod (SingleLinkedList) ) ) ==NULL)
exit (1); /* 分配空間給q結點 */
q -> data = x;
q -> next = p ->next; /* q用p的指針域 */
p -> next = q; /* p的指針域指向q */
return 1;
}
⑤刪除
int ListDelete (SingleLinkedList * head, int i, ElemType * x)
{
SingleLinkedList *p,*s;
int j;
p = head;
j = -1;
while ( p -> next != NULL && p -> next -> next != NULL && j < i-1)
{
p = p -> next;
j ++;
}
if (j != i-1)
{
printf ("刪除位置參數錯!");
return 0;
}
s = p -> next;
*x = s -> data;
p -> next = s -> next;
free (s);
return 1;
}
⑥單鏈表的釋放
void ListDestroy (SingleLinkedList * * head)
{
SingleLinkedList *p, *p1;
p = *head;
while (p != NULL)
{
p1 = p;
p = p -> next;
free (p1);
}
*head = NULL;
}

雙向鏈表
prior
data
next
結點
定義:
typedef struct DoubleNode
{
ElemType data;
struct DoubleNode * prior, * next;
}DoubleLinkedList
操作:
①插入
s爲新結點 s要插在P的前面
s -> prior = p -> prior;
p -> prior ->next = s;
s -> next =p;
p -> prior = s
②刪除
p -> prior -> next = p ->next;
p -> next -> prior = p ->prior;
free (p);
循環鏈表
在尾部的指針域指向頭結點 構成循環
靜態鏈表
在數組中增加一個指針域用來存放上一個數據元素在數組中的下標,從而構成一個鏈表,有點像順序表和鏈表的結合。

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