3.静态链表

//
//  main.c
//  03-静态链表
//
//  Copyright © 2017年 Mr.Young. All rights reserved.
//

#include <stdio.h>
#include <stdlib.h>

#define OK      1
#define ERROR   0
#define TRUE    1
#define FALSE   0
#define OVERFLOW    0

#define MAXSIZE     100 //链表的最大长度

typedef int Status;
typedef int BOOL;
typedef int ElemType;

typedef struct {
    ElemType data;
    int cur;
}component, SLinkList[100];

/**
 将一维数组space中各分量链成一个备用链表,space[0].cur为头指针,“0”表示空指针
 */
void InitSpace_SL(SLinkList *space) {
    for (int i = 0; i < MAXSIZE-1 ; i++)
        (*space)[i].cur = i+1;
    (*space)[MAXSIZE-1].cur = 0;
    (*space)[MAXSIZE-2].cur = 0; // 备用链表最后一个元素置为空
}

/**
 若备用空间链表非空,则返回分配的结点下标,否则返回0
 */
int Malloc_SL(SLinkList *space) {
    int i = (*space)[0].cur;
    if ((*space)[0].cur) // 静态链表不为空
        (*space)[0].cur = (*space)[i].cur;
    return i;
}

/**
 将下标为k的空闲结点回收到备用链表
 */
void Free_SL(SLinkList *space, int k) {
    (*space)[k].cur = (*space)[0].cur;
    (*space)[0].cur = k;
}

/**
 销毁静态链表L,L不再存在
 */
Status DestroySLinkList(SLinkList *L) {
    int i = (*L)[MAXSIZE-1].cur; // 获取链表中第一个结点的下标
    while ((*L)[i].cur) {
        i = (*L)[i].cur;
    } // 循环得到最后一个结点的下标
    (*L)[i].cur = (*L)[0].cur;
    (*L)[0].cur = (*L)[MAXSIZE-1].cur;
    (*L)[MAXSIZE-1].cur = 0; // 将静态链表的头结点设为空
    return OK;
}

/**
 将值为s的结点插入在第一个结点之前
 */
Status InsFirst(SLinkList *L, int s) {
    int i = (*L)[MAXSIZE-1].cur; // 获取链表中第一个结点的下标
    int m = Malloc_SL(L); // 分配一个下标为m的新结点
    (*L)[MAXSIZE-1].cur = m;
    (*L)[m].cur = i;
    (*L)[m].data = s;
    return OK;
}

/**
 已知h指向线性链表的头结点,删除链表中的第一个结点并以q返回
 */
Status DelFirst(SLinkList *L, ElemType *e) {
    int i = (*L)[MAXSIZE-1].cur; // 获取第一个结点的下标
    *e = (*L)[i].data;
    (*L)[MAXSIZE-1].cur = (*L)[i].cur;
    Free_SL(L, i);
    return OK;
}

/**
 删除静态链表L中的尾结点并以e返回
 */
Status Remove(SLinkList *L, ElemType *e) {
    int i = (*L)[MAXSIZE-1].cur; // 获取第一个结点的下标
    if (!(*L)[i].cur) { // 如果静态链表中只有一个结点
        (*L)[MAXSIZE-1].cur=(*L)[i].cur;
        Free_SL(L, i);
    }
    int j = (*L)[i].cur;
    while ((*L)[j].cur) {
        i = (*L)[i].cur;
        j = (*L)[i].cur;
    }
    *e = (*L)[j].data;
    Free_SL(L, j);
    (*L)[i].cur = 0;
    return OK;
}

/**
 若线性链表L为空表,则返回TRUE,否则返回FALSE
 */
BOOL ListEmpty(SLinkList L) {
    return L[MAXSIZE-1].cur==0;
}

/**
 返回线性链表L中元素的个数
 */
int ListLength(SLinkList L) {
    int i = L[MAXSIZE-1].cur; // 获取第一个结点的下标
    int len = 0;
    while (i) {
        len++;
        i = L[i].cur;
    }
    return len;
}

/**
 返回静态链表中位序为i的数据元素的值
 */
ElemType GetCurElem(SLinkList L, int k) {
    if (k<1 || k>ListLength(L)) {
        printf("访问的位置不合法!\n");
        exit(OVERFLOW);
    }
    int i = L[MAXSIZE-1].cur; // 获取第一个结点的下标
    int j = 1;
    while (j!=k && i) {
        i = L[i].cur;
        j++;
    }
    return L[i].data;
}

/**
 返回静态链表中第一个与e相等的结点位序
 */
int LocatePos(SLinkList L, ElemType e) {
    int i = L[MAXSIZE-1].cur; // 获取第一个结点的下标
    int j = 0;
    while (i) {
        ++j;
        if (L[i].data==e)
            return j;
        i=L[i].cur;
    }
    return 0;
}

/**
 已知cur_e为静态链表L中的一个结点的数据,并用pri_e保存该结点的直接前驱的数据,若无前驱,则返回ERROR
 */
Status PriorElem(SLinkList L, ElemType cur_e, ElemType *pri_e) {
    int i = L[MAXSIZE-1].cur; // 获取第一个结点的下标
    if (L[i].data==cur_e) {
        printf("该结点没有前驱结点!\n");
        return ERROR;
    }
    int j;
    while (i) {
        j = L[i].cur; // j指向i的下一个结点
        if (j && L[j].data == cur_e) {
            *pri_e = L[i].data;
            return OK;
        }
        i = j;
    }
    return ERROR;
}

/**
 已知cur_e为静态链表L中的一个结点的数据,并用next_e保存该结点的直接后继的数据,若无前驱,则返回ERROR
 */
Status NextElem(SLinkList L, ElemType cur_e, ElemType *next_e) {
    int i = L[MAXSIZE-1].cur; // 获取第一个结点的下标
    int j;
    while (i) {
        j = L[i].cur;
        if (j && L[i].data==cur_e) {
            *next_e = L[j].data;
            return OK;
        }
        i = j;
    }
    printf("该结点没有后继结点!\n");
    return ERROR;
}

/**
 在静态链表L中的第k个位置之前插入数据为e的结点
 */
Status ListInsert(SLinkList *L, int k, ElemType e) {
    if (k<1 || k>ListLength(*L)+1) {
        printf("插入的位置不合法!\n");
        return ERROR;
    }
    if (k==1) {
        InsFirst(L, e);
        return OK;
    }
    int i = (*L)[MAXSIZE-1].cur;
    int j = 1;
    while (i && j<k-1) {
        ++j;
        i = (*L)[i].cur;
    }
    int m = (*L)[i].cur; // m指向第k个结点
    int new = Malloc_SL(L); // 从静态表中找出一个空闲结点下标
    (*L)[new].cur = m;
    (*L)[new].data = e;
    (*L)[i].cur = new;
    return OK;
}

/**
 在静态链表L中,删除第k个结点,并用e保存第k个位置的值
 */
Status ListDelete(SLinkList *L, int k, ElemType *e) {
    if (k<1 || k>ListLength(*L)) {
        printf("删除的位置不合法!\n");
        return ERROR;
    }
    int i = (*L)[MAXSIZE-1].cur; // 获取第一个结点的下标
    int j = 1;
    while (i && j <k-1) { // 找到第k-1个结点位置
        j++;
        i = (*L)[i].cur;
    }
    int m = (*L)[i].cur; // 第k个结点的下标
    (*L)[i].cur = (*L)[m].cur;
    *e = (*L)[m].data;
    Free_SL(L, m);
    return OK;
}

/**
 遍历静态链表L
 */
void ListTraverse(SLinkList L) {
    int i = L[MAXSIZE-1].cur; // 获取静态链表第一个结点的下标
    int j = 0;
    while (i) {
        j++;
        printf("第%d个结点的值为:%d\n", j, L[i].data);
        i = L[i].cur;
    }
}

int main(int argc, const char * argv[]) {
    
    SLinkList *L = (SLinkList *)malloc(sizeof(SLinkList));
//    SLinkList *L = (SLinkList *)malloc(sizeof(component)*MAXSIZE);
    InitSpace_SL(L);
//    for (int i = 0; i < MAXSIZE; i++) {
//        printf("%d\n", (*L)[i].cur);
//    }
    printf("length = %d\n", ListLength(*L));
    InsFirst(L, 1);
    InsFirst(L, 2);
    InsFirst(L, 3);
    ListInsert(L, 1, 10);
    ListInsert(L, 5, 5);
    ListTraverse(*L);
    ElemType remove;
    Remove(L, &remove);
    printf("remove last is %d\n", remove);
    printf("length = %d\n", ListLength(*L));
    
    DestroySLinkList(L);
    free(L);
    return 0;
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,264评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,549评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,389评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,616评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,461评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,351评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,776评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,414评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,722评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,760评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,537评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,381评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,787评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,030评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,304评论 1 252
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,734评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,943评论 2 336

推荐阅读更多精彩内容