线性表

线性表
数据之间为线性关系,数据元素“一个接一个的排列”
在一个线性表中数据元素的类型必须是相同的。
一般只是存储查询数据就用顺序表,如果更改数据频繁就用链式表
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);
循环链表
在尾部的指针域指向头结点 构成循环
静态链表
在数组中增加一个指针域用来存放上一个数据元素在数组中的下标,从而构成一个链表,有点像顺序表和链表的结合。

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