線性表總結(c語言)
阿新 • • 發佈:2019-01-25
線性表
線性表特點
- 存在一個唯一的一個被稱作”第一個”的資料元素
- 存在唯一的一個被稱做”最後一個”的資料元素
- 除第一個之外,集合中的每個資料元素均只有一個前驅
- 除最後一個之外,集合中每個資料元素均只有一個後繼
定義
一個線性表是n個數據元素的有限序列。
演算法設定
順序表和線性連結串列
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
//順序表
typedef struct{
ElemType * elem;
int length;
int listsize;
}SqList;
//連結串列
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
基本操作
/*
InitList(&L); //構造一個空線性表L
DestoryList(&L); //銷燬線性表
ClearList(&L); //清空線性表
ListEmpty(L); //判空
ListLength(K); //返回線性表長度
GetElem(L,i,&e); //傳入L線性表,i索引,返回e
LocateElem(L,e,compare()) //返回第一個與e滿足關係的資料元素位序,不存在則返回0
PriorElem(L,cur_e,&pre_e) //若cur_e是L的資料元素,且不是第一個,則用pre_e返回他的前驅。
NextElem(L,cur_e,&next_e) //若cur_e是L的資料元素,且不是最後一個,用next_e返回他的後繼
ListInsert(&L,i,e) //在L中第i個位置之前插入新的資料元素e,L的長度加1
ListDelete(&L,i,&e) //刪除L的第i個數據元素,並呼叫e返回其值,L的長度減1
ListTraverse(L,visit()) //依次對L的每個資料元素呼叫函式visit()。一旦visit()失敗,則操作失敗
*/
線性表(順序儲存結構)
#include <stdio.h>
#include <stdlib.h>
#include "sequenceList.h"
bool compare(ElemType e1,ElemType e2) {
return e1 == e2 ? TRUE : FALSE;
}
void visit(ElemType e) {
printf("%d ", e);
}
Status InitList(SqList &L) {
//創造一個空表
L.elem = (ElemType *)malloc(sizeof(ElemType)*LIST_INIT_SIZE);
if (!L.elem)
{
exit(OVERFLOW);
}
L.length = 0;
L.listsize = LIST_INIT_SIZE;
return OK;
}
Status ListEmpty(SqList L)
{
//判空
return L.length == 0 ? TRUE : FALSE;
}
int ListLength(SqList L)
{
//返回線性表長度
return L.length;
}
Status GetElem(SqList L,int i,ElemType &e) //傳入L線性表,i索引,返回e
{
//先判斷索引的合法性
if (i < 0 || i >= L.length)
{
return FALSE;
}
e = L.elem[i];
return TRUE;
}
void ClearList(SqList &L) //清空線性表
{
L.length = 0;
}
void DestoryList(SqList &L) //銷燬線性表
{
free(L.elem);
L.length = L.listsize = 0;
}
int LocateElem(SqList L,ElemType e,bool (*compare)(ElemType,ElemType)) //返回第一個與e滿足關係的資料元素位序,不存在則返回-1 compare
{
for (int i = 0; i < L.length; i++)
{
if (compare(L.elem[i],e))
{
return i;
}
}
return -1;
}
Status PriorElem(SqList L,ElemType cur_e,ElemType &pre_e)
{
//若cur_e是L的資料元素,且不是第一個,則用pre_e返回他的前驅。
for (int i = 1; i < L.length; i++)
{
if (L.elem[i] == cur_e)
{
pre_e = L.elem[i - 1];
return TRUE;
}
}
return FALSE;
}
Status NextElem(SqList L, ElemType cur_e, ElemType &next_e)
{
//若cur_e是L的資料元素,且不是最後一個,用next_e返回他的後繼
for (int i = 0; i < L.length - 1; i++)
{
if (L.elem[i] == cur_e)
{
next_e = L.elem[i + 1];
return TRUE;
}
}
return FALSE;
}
Status ListInsert(SqList &L,int i,ElemType e)
{
//在L中第i個位置之前插入新的資料元素e,L的長度加1
//1.判斷i的合法性
if (i < 0|| i > L.length)
{
return FALSE;
}
//2.判斷線性表長度夠不夠,不夠,realloc
if (L.listsize == L.length)
{
L.listsize += LISTINCREMENT;
L.elem = (ElemType *)realloc(L.elem, L.listsize);
if (!L.elem)
{
exit(OVERFLOW);
}
}
//3.將i元素向後以一個單位 從後向前移動
for (int j = L.length; j > i; j--)
{
L.elem[j] = L.elem[j - 1];
}
//4.插入e
L.elem[i] = e;
L.length++;
return TRUE;
}
Status ListDelete(SqList &L,int i,ElemType &e)
{
//刪除L的第i個數據元素,並呼叫e返回其值,L的長度減1
//1.判斷i的合法性
if (i < 0 || i >= L.length)
{
return FALSE;
}
//2.將索引為i的元素取出來,賦值給e
e = L.elem[i];
//3.i後面的元素向前移動1個單位,從前向後移動 j最後位置在倒數第二個位置,索引為L.length - 2
for (int j = i; j < L.length - 1; j++)
{
L.elem[j] = L.elem[j + 1];
}
L.length--;
return TRUE;
}
void ListTraverse(SqList L,void (*visit)(ElemType))
{
//依次對L的每個資料元素呼叫函式visit()。一旦visit()失敗,則操作失敗
for (int i = 0; i < L.length; i++)
{
visit(L.elem[i]);
}
}
線性表(鏈式儲存結構)
2.10指出以下演算法中的錯誤和低效(即費時)之處,並將它改寫為一個及正確又高效的演算法
Status DeleteK(SqList &a, int i,int k) {
//本過程從順序儲存結構的線性表a中刪除第i個元素起的k個元素
if (i < 1|| k < 0|| i+k>a.length)
{
return INFEASIBLE;
}
else
{
for (int count = 0; count < k; count++)
{
for (int j = a.length; j >= i + 1; j--) {
a.elem[j - 1] = a.elem[j];
a.length--;
}
}
}
return OK;
}