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