1. 程式人生 > >資料結構:連結串列(指標+遊標)

資料結構:連結串列(指標+遊標)

指標實現連結串列

沒什麼好廢話的, 註釋在程式碼中

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

typedef int ElementType;//元素型別
typedef node* PtrToNode;//指向元素的指標
typedef PtrToNode List;//連結串列的表頭的指標
typedef PtrToNode position;//連結串列中位置的指標 以上三個都是Node型別的指標

//連結串列的單體元素
struct node{
    ElementType element;
    node*
next; }; //測試是不是空表 bool IsEmpty(List L) { return L->next == NULL; } //測試當前位置是不是連結串列的末尾 bool IsLast(position P, List L) { return P->next == NULL; } //find例程用來查詢元素X position Find(ElementType X, List L) { position P; P = L ->next; while(P != NULL && P->element !=
X)//如果當期那值不是那麼向前繼續查詢 P = P->next; return P; } //尋找元素X的上一個位置 position FindPrivious(ElementType x, List L) {//這個函式另一種實現方式是在FindElement函式中使用兩個指標一個指向前一個元素, 另一個指向當前元素 position P; P = L; while(P->next != NULL && P->next->element != x) P = P->next; return
P; } //刪除元素X void Delete(ElementType X, List L) { position P, TmpCell; P = FindPrivious(X, L); if(!IsLast(P, L))//判斷是不是在末尾, 如果在末尾不進行操作 { TmpCell = P->next; P->next = TmpCell->next; free(TmpCell); } } //插入元素X void Insert(ElementType X, List L, position P) { position TmpCell; TmpCell = (node*)malloc(sizeof(node));//分配記憶體並強制轉化為node型別 if(TmpCell == NULL) printf("Fail to malloc\n"); TmpCell -> element = X; TmpCell -> next = P->next; P->next = TmpCell; }

遊標實現連結串列

在一些語言中不支援指標的操作(BASIC等), 另外連結串列的指標實現中, malloc和free也是比較費時間的(競賽狗傷不起), 而且還會造成記憶體碎片的問題(當然競賽中不會有什麼嚴重的後果)。這裡我們試著用遊標來實現一下這個ADT。

註釋在程式碼中

#include<cstdio>
#include<cstring>
#include<algorithm>
#define SpaceSize 10000

using namespace std;

typedef int ElementType;
typedef int PtrNode;
typedef PtrNode List;
typedef PtrNode Position;

struct node{
    ElementType Element;
    Position Next;
}CursorSpace[SpaceSize];//這裡我們可以看做兩個陣列CursorSpace和List這個串起來的陣列

//List下的那個陣列代表的是連結串列中的現有元素
//我們通過malloc得到元素的操作就是將CursorSpace陣列中的元素放用List串起來
//仿照malloc進行的分配遊標的操作
static Position CurSorAlloc(void)
{
    Position P;

    P = CursorSpace[0].Next;
    CursorSpace[0].Next = CursorSpace[P].Next;

    return P;
}

//回收遊標的操作, 將回收的遊標插入CursorSpace陣列中的0的後面
static void CursorFree(Position P)
{
    CursorSpace[P].Next = CursorSpace[0].Next;
    CursorSpace[0].Next = P;
}

//判斷是不是空表, 這裡的0就行是指標的NULL
bool IsEmpty(List L)
{
    return CursorSpace[L].Next == 0;
}

//判斷當前是不是檔案的結尾
bool IsLast(Position P, List L)
{
    return CursorSpace[P].Next == 0;
}

//尋找x元素的位置
Position Find(ElementType x, List l)
{
    Position p;

    p = CursorSpace[l].Next;
    while(p && CursorSpace[p].Element != x)
        p = CursorSpace[p].Next;

    return p;
}

//尋找x元素的前置元素
Position FindPrevious(ElementType x, List l)
{
    Position p;

    p = l;

    while(p && CursorSpace[CursorSpace[p].Next].Next != x)
        p = CursorSpace[p].Next;

    return p;
}

//刪除元素x, 在這裡注意這個是放掉的元素是通過CurseFree放回了CursorSpace陣列中第一個元素的後面
void Delete(ElementType x, List l)
{
    Position P, TmpCell;

    P = FindPrevious(x, l);

    if(!IsLast(P, l))
    {
        TmpCell = CursorSpace[P].Next;
        CursorSpace[P].Next = CursorSpace[TmpCell].Next;
        CursorFree(TmpCell);
    }
}

//插入, 這裡要注意的是next中儲存的是數字也就是下一個元素在CursorSpace陣列的中標號
void Insert(ElementType x, List L, Position P)
{
    Position TmpCell;

    TmpCell = CurSorAlloc();
    if(TmpCell == 0)
        printf("Fail to malloc\n");

    CursorSpace[TmpCell].Element = x;
    CursorSpace[TmpCell].Next = CursorSpace[P].Next;
    CursorSpace[P].Next = TmpCell;

}