数据结构:链表(指针+游标)

指针实现链表

没什么好废话的, 注释在代码中

#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;

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