C++ - 链表

#include "stdafx.h"
#include <Windows.h>

typedef struct tagStudent
{
    int id;
    char szName[128];
    tagStudent * pNext;

}_STUDENT_ST;

// 初始化链表头节点
_STUDENT_ST g_stListHead = {0,0,0};
// 链表
_STUDENT_ST g_stuList[4] = 
{
    { 1001, "张三", 0 },
    { 1002, "李四", 0 },
    { 1003, "王五", 0 },
    { 1004, "赵六", 0 }
};

// 遍历链表
BOOL TraverseList(_STUDENT_ST * plstObj)
{
    if (NULL == plstObj->pNext)
    {
        return FALSE;
    }
    _STUDENT_ST * pstTmp = plstObj->pNext;
    while (pstTmp)
    {
        printf("%d %s \r\n", pstTmp->id, pstTmp->szName);
        pstTmp = pstTmp->pNext;
    }
    return TRUE;
}

// 插入链表 - 头部插入
BOOL InsertListHead(_STUDENT_ST * pstTarList, _STUDENT_ST * stInsterObj)
{    
    // 1. 首先, 将头节点指向的原链表第一个节点地址传递给要插入的节点的pNext
    stInsterObj->pNext = pstTarList->pNext;
    // 2. 其次, 再将要插入的节点的地址传递给头节点的pNext
    pstTarList->pNext = stInsterObj;
    if (pstTarList->pNext)
    {
        // 3. 插入成功, 返回TRUE
        return TRUE;
    }
    // 4. 插入失败, 返回FALSE
    return FALSE;
}

// 插入链表 - 尾部插入
BOOL InsertListEnd(_STUDENT_ST * pstTarList, _STUDENT_ST * pstInsterObj)
{
    // 首先, 遍历链表pstTarList直到链表尾
    while(pstTarList->pNext)
    {
        pstTarList = pstTarList->pNext;
    }

    // 其次, 将要插入的节点赋值给链表的pNext
    pstTarList->pNext = pstInsterObj;
    
    // 再次, 将插入节点的pNext赋值为0,标识为链表尾
    pstInsterObj->pNext = 0;

    // 最后, 检测是否插入成功.
    if ( 0 != pstTarList->pNext)
    {
        return TRUE;
    }

    return FALSE;

}

// 从链表中间某个节点插入
void InterveningList(const int iNum, _STUDENT_ST * pstList, _STUDENT_ST * pstInsertObj)
{
    // 当前的节点
    _STUDENT_ST * pstCurNode = pstList->pNext;
    // 如果, 当前的链表为空链表
    if (0 == pstCurNode)
    {
        // 直接插入到尾部, 然后返回
        InsertListEnd(pstList, pstInsertObj);
        return;
    }
    while (pstCurNode)
    {
        if (iNum == pstCurNode->id)
        {
            break;
        }
        pstCurNode = pstCurNode->pNext;
    }
    
    // 将要指定节点(iNum对应的节点)pNext中保存的下一个节点的地址传给要插入的节点pNext
    pstInsertObj->pNext = pstCurNode->pNext;
    // 然后再将要插入节点的地址传给指定节点的pNext中保存.
    pstCurNode->pNext = pstInsertObj;
}


// 删除链表的指定节点
void DeleteNode(const int iNum, _STUDENT_ST * pstList)
{
    _STUDENT_ST * pstCurNode = pstList->pNext;
    _STUDENT_ST * pstTmp = pstList;
    if (0 == pstCurNode)
    {
        // 如果是空链表,直接返回
        return ;
    }

    while (pstCurNode)
    {
        // 如果当前遍历的节点id和要删除的链表节点id相匹配
        if (iNum == pstCurNode->id)
        {
            // 如果匹配, 则将当前节点pNext中指向下一个节点的地址
            // 保存到当前节点的上一个节点pNext中
            pstTmp->pNext = pstCurNode->pNext;
            break;
        }
        // 将当前节点的信息保存在临时链表临时节点中
        pstTmp = pstCurNode;
        // 并将链表指向下一个节点,继续遍历
        pstCurNode = pstCurNode->pNext;
    }

}

int _tmain(int argc, _TCHAR* argv[])
{
    ////////////////////////////////【 链表 - 初始化 】///////////////////////////////
    // 将链表第一个节点的地址加入到链表头节点
    g_stListHead.pNext = &g_stuList[0];
    g_stuList[0].pNext = &g_stuList[1];
    g_stuList[1].pNext = &g_stuList[2];
    g_stuList[2].pNext = &g_stuList[3];
    // 将链表的最后一个节点的pNext赋值为NULL,代表链表结束
    g_stuList[3].pNext = 0;

    ////////////////////////////////【 遍历 】///////////////////////////////
    TraverseList(&g_stListHead);

    
    ////////////////////////////////【 插入链表 】///////////////////////////////
    // 1. 头部插入
    printf("\r\n\r\n===========【 链表 - 头部插入 】============\r\n");
    _STUDENT_ST stStuTmp = { 1005, "孙七", 0 };
    InsertListHead(&g_stListHead, &stStuTmp);
    TraverseList(&g_stListHead);

    // 2. 尾部插入
    printf("\r\n\r\n===========【 链表 - 尾部插入 】============\r\n");
    _STUDENT_ST stStuTmp2 = { 1006, "周八", 0 };
    InsertListEnd(&g_stListHead, &stStuTmp2);
    TraverseList(&g_stListHead);

    // 3. 从链表某个节点插入
    printf("\r\n\r\n===========【 链表 - 中间某个节点插入 】============\r\n");
    _STUDENT_ST stStuTmp3 = { 1007, "吴九", 0};
    InterveningList(1004, &g_stListHead, &stStuTmp3);
    TraverseList(&g_stListHead);

    // 4. 测试插入空链表
    printf("\r\n\r\n===========【 链表 - 插入空链表 】============\r\n");
    _STUDENT_ST pstEmptyListHeader = {0};            // 创建一个空链表头
    _STUDENT_ST stStuTmp4 = { 10001, "九江高线", 0};    // 创建一个链表节点
    InterveningList(1, &pstEmptyListHeader, &stStuTmp4);
    TraverseList(&pstEmptyListHeader);

    ////////////////////////////////【 删除链表节点 】///////////////////////////////
    printf("\r\n\r\n===========【 链表 - 删除指定节点 】============\r\n");
    DeleteNode(1005, &g_stListHead);    // 删除节点1005
    DeleteNode(1006, &g_stListHead);    // 删除节点1006
    DeleteNode(1007, &g_stListHead);    // 删除节点1007
    TraverseList(&g_stListHead);


    getchar();
    return 0;
}

posted @ 2016-08-04 15:23  C/C++/Python/Java  阅读(235)  评论(0编辑  收藏  举报