单链表的算法 -电脑资料

电脑资料 时间:2019-01-01 我要投稿
【www.unjs.com - 电脑资料】

    要点

    单链表的结构可表示如下:

    typedef int ElemType;

    typedef struct LNode {

    ElemType data;

    struct LNode* next;

    } LNode, *LinkList;

    基本算法

    插入结点

    假设要在单链表的a结点和b结点之间插入一个值为x的新结点,

单链表的算法

    如下图所示,指针s指向一个值为x的结点,为了插入s。

    首先让s的next指针指向b,即s->next = p->next;

    然后,让a的next指针指向s,即p->next = s;

    删除结点

    假设要删除单链表中的b结点。

    首先,找到b结点前面的结点a。

    如下图所示,p指针指向a结点。b的下一个结点就是p->next->next。

    所以,只要让p的next指针跳过b结点,指向b的下一个结点就OK了,即p->next = p->next->next;

    参考代码

    以下为本人实现的单链表的基本操作。欢迎指正。本人的编译环境为Visual Studio2010,C语言。

    基本操作

    /***********************************************************************************************************************

    [单链表操作]

    [1] destroyList, 销毁单链表

    [2] initList, 初始化一个带头结点的空单链表,如果传入一个不为空的单链表,将被重置

    [3] insertElem, 在单链表中第 i 个位置插入元素 elem

    [4] removeElem, 在单链表中移除第 pos 个元素,并由 elem 返回其值

    [5] createList, 根据数组 elems 构建一个单链表

    [6] isEmptyList, 判断单链表是否为空

    [7] getElem, 获取单链表上位置为 pos 的元素

    [8] locateElem, 获取元素 elem 在单链表上第一次出现的位置,如果不存在返回 -1

    [9] getLength, 获取单链表长度

    [10] printList, 打印整个单链表

    [11] reverseList, 反转单链表

    ***********************************************************************************************************************/

    #include

    #include

    /***********************************************************************************************************************

    第一部分,数据结构、宏定义

    ***********************************************************************************************************************/

    #define MAX 5

    typedef enum {

    K = 0,

    ERROR = 1

    } STATUS_EN;

    typedef enum {

    TRUE = 0,

    FALSE = -1

    } BOOL;

    typedef int ElemType;

    typedef struct LNode {

    ElemType data;

    struct LNode* next;

    } LNode, *LinkList;

    /***********************************************************************************************************************

    第二部分,函数实现

    ***********************************************************************************************************************/

    /*******************************************************************************

    Funtion   : [1] destroyList

    Description : 销毁单链表

    Input    : struct LNode **ppHead

    Output   : struct LNode **ppHead

    Return Value : STATUS_EN(OK/ERROR)

    Author   : VictorZhang

    Date    : 2015-03-30

    *******************************************************************************/

    void destroyList(struct LNode **ppHead) {

    LNode *p = *ppHead;

    LNode *q = p->next;

    // 先遍历删除所有元素

    while (p && p->next) {

    q = p->next;

    p = q->next;

    free(q);

    q = NULL;

    }

    // 最后释放头结点

    free(*ppHead);

    *ppHead = NULL;

    }

    /*******************************************************************************

    Funtion   : initList

    Description : 初始化一个带头结点的空单链表,如果传入一个不为空的单链表,

    将被重置

    Input    : struct LNode **ppHead

    Output   : struct LNode **ppHead

    Return Value : STATUS_EN(OK/ERROR)

    Author   : VictorZhang

    Date    : 2015-03-30

    *******************************************************************************/

    STATUS_EN initList(struct LNode **ppHead) {

    if (*ppHead)

    destroyList(ppHead);

    LNode *p = (LNode*)malloc(sizeof(LNode));

    p->next = NULL;

    p->data = 0;

    *ppHead = p;

    return OK;

    }

    /*******************************************************************************

    Funtion   : insertElem

    Description : 在单链表中第 i 个位置插入元素 elem

    Input    : struct LNode **ppHead,

    const int pos,

    const ElemType elem

    Output   : struct LNode **ppHead

    Return Value : STATUS_EN(OK/ERROR)

    Author   : VictorZhang

    Date    : 2015-03-30

    *******************************************************************************/

    STATUS_EN insertElem(struct LNode **ppHead, const int pos, const ElemType elem) {

    LNode *p = *ppHead;

    LNode *s = NULL;

    // 寻找链表当前最后一个结点

    int i = 0;

    while (p && i < pos) {

    p = p->next;

    i++;

    }

    // 未找到末尾结点

    if (!p || i > pos)

    return ERROR;

    // 生成新结点

    s = (LNode*) malloc (sizeof(LNode));

    if (!s)

    return ERROR;

    // 插入单链表中

    s->data = elem;

    s->next = p->next;

    p->next = s;

    return OK;

    }

    /*******************************************************************************

    Funtion   : removeElem

    Description : 在单链表中移除第 pos 个元素,并由 elem 返回其值

    Input    : struct LNode **ppHead,

    const int pos,

    ElemType *pElem

    Output   : struct LNode **ppHead,

    ElemType *pElem

    Return Value : STATUS_EN(OK/ERROR)

    Author   : VictorZhang

    Date    : 2015-03-30

    *******************************************************************************/

    STATUS_EN removeElem(struct LNode **ppHead, const int pos, ElemType *pElem) {

    LNode *p = *ppHead;

    LNode *q = NULL;

    int i = 0;

    while (p && p->next && i < pos) {

    p = p->next;

    i++;

    }

    // 删除位置不合理

    if (!(p->next) || i > pos)

    return ERROR;

    // 删除并释放结点

    q = p->next;

    p->next = q->next;

    *pElem = q->data;

    free(q);

    return OK;

    }

    /*******************************************************************************

    Funtion   : createList

    Description : 根据数组 elems 构建一个单链表

    Input    : struct LNode **ppHead,

    const ElemType elems[],

    const int n

    Output   : struct LNode **ppHead

    Return Value : STATUS_EN(OK/ERROR)

    Author   : VictorZhang

    Date    : 2015-03-30

    *******************************************************************************/

    STATUS_EN createList(struct LNode **ppHead, const ElemType elems[], const int n) {

    int i = 0;

    STATUS_EN statu = OK;

    // 按序将数组元素插入到单链表尾部

    for (i = 0; i < n; i++) {

    statu = insertElem(ppHead, i, elems[i]);

    if (OK != statu)

    return statu;

    }

    return OK;

    }

    /*******************************************************************************

    Funtion   : isEmptyList

    Description : 判断单链表是否为空

    Input    : struct LNode *pHead

    Output   : N/A

    Return Value : BOOL

    Author   : VictorZhang

    Date    : 2015-03-30

    *******************************************************************************/

    BOOL isEmptyList(struct LNode *pHead) {

    if (NULL == pHead || NULL == pHead->next)

    return TRUE;

    else

    return FALSE;

    }

    /*******************************************************************************

    Funtion   : getElem

    Description : 获取单链表上位置为 pos 的元素

    Input    : struct LNode *pHead,

    const int pos,

    ElemType *pElem

    Output   : ElemType *pElem

    Return Value : STATUS_EN(OK/ERROR)

    Author   : VictorZhang

    Date    : 2015-03-30

    *******************************************************************************/

    STATUS_EN getElem(struct LNode *pHead, const int pos, ElemType *pElem) {

    int i = 0;

    LNode *p = pHead->next;

    while (p && i <= pos) {

    if (i == pos) {

    *pElem = p->data;

    return OK;

    } else {

    p = p->next;

    i++;

    }

    }

    return ERROR;

    }

    /*******************************************************************************

    Funtion   : locateElem

    Description : 获取元素 elem 在单链表上第一次出现的位置,如果不存在返回 -1

    Input    : struct LNode *pHead,

    const ElemType elem

    Output   : N/A

    Return Value : int

    Author   : VictorZhang

    Date    : 2015-03-30

    *******************************************************************************/

    int locateElem(struct LNode *pHead, const ElemType elem) {

    int pos = 0;

    LNode *p = pHead->next;

    while (p) {

    if (p->data == elem) {

    return pos;

    } else {

    pos++;

    p = p->next;

    }

    }

    return -1;

    }

    /*******************************************************************************

    Funtion   : getLength

    Description : 获取单链表长度

    Input    : struct LNode *pHead

    Output   : N/A

    Return Value : int

    Author   : VictorZhang

    Date    : 2015-04-02

    *******************************************************************************/

    int getLength(struct LNode *pHead) {

    if (NULL == pHead || NULL == pHead->next) {

    return 0;

    }

    int i = 0;

    LNode *p = pHead->next;

    while (p) {

    p = p->next;

    i++;

    }

    return i;

    }

    /*******************************************************************************

    Funtion   : printList

    Description : 打印整个单链表

    Input    : struct LNode *pHead

    Output   : N/A

    Return Value : N/A

    Author   : VictorZhang

    Date    : 2015-04-02

    *******************************************************************************/

    void printList(struct LNode *pHead) {

    if (NULL == pHead || NULL == pHead->next) {

    printf("LinkList is empty\n");

    return;

    }

    LNode *p = pHead->next;

    printf("LinkList:");

    while (p) {

    printf(" %d", p->data);

    p = p->next;

    }

    printf("\n");

    }

    /*******************************************************************************

    Funtion   : reverseList

    Description : 反转单链表

    Input    : struct LNode **ppHead

    Output   : struct LNode **ppHead

    Return Value : N/A

    Author   : VictorZhang

    Date    : 2015-04-02

    *******************************************************************************/

    void reverseList(struct LNode **ppHead) {

    if (NULL == *ppHead || NULL == (*ppHead)->next) {

    return;

    }

    LNode *prev = NULL;

    LNode *cur = (*ppHead)->next;

    LNode *next = NULL;

    while (cur) {

    next = cur->next;

    cur->next = prev;

    prev = cur;

    cur = next;

    }

    (*ppHead)->next = prev;

    }

    测试例部分

    /***********************************************************************************************************************

    第三部分,测试例

    ***********************************************************************************************************************/

    void testCase0() {

    printf("================== testCase0 ==================\n");

    int len = 0;

    BOOL bFlag = FALSE;

    ElemType A[MAX] = {4,5,2,1,3};

    struct LNode *pHead = NULL;

    // 初始化链表

    initList(&pHead);

    printf("Init List\n");

    // 获取链表长度

    len = getLength(pHead);

    printf("Length of List is %d\n", len);

    // 根据一个数组来创建单链表

    createList(&pHead, A, MAX);

    printf("After create List:\n");

    printList(pHead);

    // 获取链表长度

    len = getLength(pHead);

    printf("Length of List is %d\n", len);

    // 判断单链表是否为空

    bFlag = isEmptyList(pHead);

    if (bFlag) {

    printf("It is a empty List.\n");

    } else {

    printf("It is not a empty List.\n");

    }

    // 销毁链表

    printf("Destroy List\n");

    destroyList(&pHead);

    // 获取链表长度

    len = getLength(pHead);

    printf("Length of List is %d\n", len);

    // 判断单链表是否为空

    bFlag = isEmptyList(pHead);

    if (bFlag) {

    printf("It is a empty List.\n");

    } else {

    printf("It is not a empty List.\n");

    }

    }

    void testCase1() {

    printf("================== testCase1 ==================\n");

    STATUS_EN statu;

    ElemType A[MAX] = {4,5,2,1,3};

    struct LNode *pHead = NULL;

    // 初始化链表

    initList(&pHead);

    printf("Init List\n");

    createList(&pHead, A, MAX);

    printf("After create List:\n");

    printList(pHead);

    // 在尾部位置尝试插入元素

    statu = insertElem(&pHead, 5, 9);

    printf("Insert element:\n");

    if (OK != statu) {

    printf("Insert failed!\n");

    } else {

    printList(pHead);

    }

    // 在头部位置尝试插入元素

    statu = insertElem(&pHead, 0, 2);

    if (OK != statu) {

    printf("Insert failed!\n");

    } else {

    printList(pHead);

    }

    // 中间位置尝试插入元素

    statu = insertElem(&pHead, 3, 7);

    if (OK != statu) {

    printf("Insert failed!\n");

    } else {

    printList(pHead);

    }

    // 尝试在不合理的位置上插入元素

    statu = insertElem(&pHead, 99, 15);

    if (OK != statu) {

    printf("Insert failed!\n");

    } else {

    printList(pHead);

    }

    }

    void testCase2() {

    printf("================== testCase2 ==================\n");

    STATUS_EN statu;

    ElemType elem;

    ElemType A[MAX] = {4,5,2,1,3};

    struct LNode *pHead = NULL;

    // 初始化链表

    initList(&pHead);

    printf("Init List\n");

    createList(&pHead, A, MAX);

    printf("After create List:\n");

    printList(pHead);

    // 尝试移除尾部位置的元素

    statu = removeElem(&pHead, 4, &elem);

    printf("Remove element pos(%d)\n", 4);

    if (OK != statu) {

    printf("Remove failed!\n");

    } else {

    printList(pHead);

    }

    // 尝试移除头部位置的元素

    statu = removeElem(&pHead, 0, &elem);

    printf("Remove element pos(%d)\n", 0);

    if (OK != statu) {

    printf("Remove failed!\n");

    } else {

    printList(pHead);

    }

    // 尝试移除中间位置的元素

    statu = removeElem(&pHead, 1, &elem);

    printf("Remove element pos(%d)\n", 1);

    if (OK != statu) {

    printf("Remove failed!\n");

    } else {

    printList(pHead);

    }

    // 尝试移除不合理位置的元素

    statu = removeElem(&pHead, 11, &elem);

    printf("Remove element pos(%d)\n", 11);

    if (OK != statu) {

    printf("Remove failed!\n");

    } else {

    printList(pHead);

    }

    }

    void testCase3() {

    printf("================== testCase3 ==================\n");

    int pos = 4;

    STATUS_EN statu;

    ElemType elem;

    ElemType A[MAX] = {4,5,2,1,3};

    struct LNode *pHead = NULL;

    // 初始化链表

    initList(&pHead);

    printf("Init List\n");

    createList(&pHead, A, MAX);

    printf("After create List:\n");

    printList(pHead);

    // 获取指定位置上的元素

    statu = getElem(pHead, pos, &elem);

    if (OK != statu) {

    printf("Get element failed!\n");

    } else {

    printf("The elem in pos(%d) is %d\n", pos, elem);

    }

    // 查找元素在单链表中第一次出现的位置

    elem = 4;

    pos = locateElem(pHead, elem);

    printf("%d is in pos(%d) of List\n", elem, pos);

    elem = 9;

    pos = locateElem(pHead, elem);

    printf("%d is in pos(%d) of List\n", elem, pos);

    }

    void testCase4() {

    printf("================== testCase4 ==================\n");

    ElemType A[MAX] = {4,5,2,1,3};

    struct LNode *pHead = NULL;

    // 初始化链表

    initList(&pHead);

    printf("Init List\n");

    createList(&pHead, A, MAX);

    printf("After create List:\n");

    printList(pHead);

    // 反转单链表

    reverseList(&pHead);

    printf("Reverse List:\n");

    printList(pHead);

    }

    int main() {

    testCase0();

    testCase1();

    testCase2();

    testCase3();

    testCase4();

    return 0;

    }

最新文章