文章目录
一、单项链表
1.自动扩容(增)
1.1扩容函数 (顺序表的尾添加)
// 扩容函数
void ZengJia ( struct Dongshuzu * pShuzu , int iShuju )
{
if ( pShuzu -> iRongliang == pShuzu -> iShuliang ) // 当容量==数量的时候需要扩容
{
// 容量变大
pShuzu -> iRongliang += 10 ;
// 申请一个新空间来装原有数据
int * pTemp = ( int * ) malloc ( sizeof ( int ) * pShuzu -> iRongliang ) ;
// 将源数据复制进新空间
for ( unsigned int i = 0 ; i < pShuzu -> iRongliang ; i ++ )
{
pTemp [ i ] = pShuzu -> pShuzutou [ i ] ;
}
// 将源空间释放
free ( pShuzu -> pShuzutou ) ;
// 将数组头指针指向新空间
pShuzu -> pShuzutou = pTemp ;
}
//将数据装进去
pShuzu->pShuzutou[pShuzu->iShuliang] = iShuju; // 数字头[数量]数量的初始值为0
// 与存储数据量++
pShuzu->iShuliang++;
}
1.2 链表的释放
// 链式链表的释放
void FreeList(struct Node* pHead)
// 链表的释放只需要传一级的指针,是需要释放链表指向的地址,如果想要在释放后把pHead的的值赋值为NULL,就需要二级指针
{
while (pHead != NULL)
{
// 如果在这里直接free(pHead)释放,则下一步的pHead就没有了,下一步就是错误的
struct Node* pt = pHead; // 用一个临时变量储存pHead
pHead = pHead->pNext;
free(pt); //释放临时变量
}
}
1.3 完整 程序
# include<stdio.h>
# include<malloc.h>
struct Dongshuzu
{
int* pShuzutou; // 首地址
unsigned int iRongliang; // 容量
unsigned int iShuliang; //已存储的数量
};
// 初始化函数
void ChuShiHua(struct Dongshuzu* pShuzu);
// 扩容函数
void ZengJia(struct Dongshuzu* pShuzu, int iShuju);
// 将数据输出
void ShuChu(struct Dongshuzu* stshuzu);
int main(void)
{
struct Dongshuzu stshuzu;
ChuShiHua(&stshuzu);
ZengJia(&stshuzu, 1);
ZengJia(&stshuzu, 2);
ZengJia(&stshuzu, 3);
ZengJia(&stshuzu, 4);
ZengJia(&stshuzu, 5);
ZengJia(&stshuzu, 6);
ShuChu(&stshuzu);
free(stshuzu.pShuzutou);
return 0;
}
// 初始化函数
void ChuShiHua(struct Dongshuzu* pShuzu)
{
pShuzu->iRongliang = 5; //设置初始容量
pShuzu->pShuzutou = malloc(sizeof(int) * pShuzu->iRongliang); //为设置的初始容量申请空间
pShuzu->iShuliang = 0; // 初始时已存储数量为0
}
// 扩容函数
void ZengJia(struct Dongshuzu* pShuzu, int iShuju)
{
if (pShuzu->iRongliang == pShuzu->iShuliang) // 当容量==数量的时候需要扩容
{
// 容量变大
pShuzu->iRongliang += 10;
// 申请空间
int* pTemp = (int*)malloc(sizeof(int) * pShuzu->iRongliang);
// 将源数据复制进新空间
for (unsigned int i = 0; i < pShuzu->iRongliang; i++)
{
pTemp[i] = pShuzu->pShuzutou[i];
}
// 将源空间释放
free ( pShuzu -> pShuzutou ) ;
// 将数组头指针指向新空间
pShuzu -> pShuzutou = pTemp ;
}
//将数据装进去
pShuzu->pShuzutou[pShuzu->iShuliang] = iShuju;
// 数组的数量是比数组的下标值大1,添加时在结尾添加,所以新添加的数据的数组下标值=数据的数量值
pShuzu->iShuliang++;// 与存储数据量++
}
// 将数据输出
void ShuChu(struct Dongshuzu* stshuzu)
{
//参数检验,如果参数是空程序就为异常,参数有指针的都要进行参数检验
if (NULL == stshuzu)
{
printf("参数错误");
return;
}
printf("容量:%u,数量:%u\n", stshuzu->iRongliang, stshuzu->iShuliang);
printf("数据:");
for (unsigned int i = 0; i < stshuzu->iShuliang; i++)
{
printf("%d ", stshuzu->pShuzutou[i]);
}
}
1.3 链表的头添加
// 头添加
void AddToHead(struct Node** pHead, struct Node** pEnd, int iData)
{
// 创建结点,用新创建的结点来装形参
struct Node* pTemp = (struct Node*)malloc(sizeof(struct Node));
// 节点成员赋值
if (pTemp != NULL)
{
// 新结点装上形参后连接
pTemp->iData = iData;
pTemp->pNext = NULL; // 尾结点赋值成空很重要
// 新结点装上形参后连接合适的位置
if (NULL == pTemp)// 如果为空新加节点既是头也是尾
{
*pEnd = pTemp;
// *pHead = pTemp;
}
else //如果不为空,新的结点的下一个结点为原来的头指针
{
pTemp->pNext = *pHead;
// *pHead = pTemp;
}
// 把新添加到头部的结点从新设置为头结点
*pHead = pTemp;
}
}
1.4 链表的尾添加
// 尾添加
void AddToEnd(struct Node** pHead, struct Node** pEnd, int iData)
//该函数的参数是指针,而该函数要修改这个指针的指向,所以参数为二级指针。
{
// 创建节点
struct Node* pTemp = (struct Node*)malloc(sizeof(struct Node));
if (pTemp != NULL)
{
// 节点成员赋值,每一个成员都要赋值
pTemp->iData = iData;
// 尤其是pTemp->pNext结点一定要赋值为空,会影响到后面的链表的操作
pTemp->pNext = NULL;
//连上去
if (*pHead == NULL) //如果链表为空
{
*pHead = pTemp;
//*pEnd = pTemp;
//空量表头和尾都是空,所以头指针和尾指针是相同的。
}
else // 如果链表原来不为空,则新的结点连到尾部
{
(*pEnd)->pNext = pTemp; //新节点练到尾部
//*pEnd = pTemp; // 尾指针指向新来的尾部添加节点
}
*pEnd = pTemp; // 两步判断里都要使尾部指针指向,新添加的尾节点可以直接放到判断外部 ,节省一步。
}
}
// 没有尾指针的尾添加
void AddToEndNoEnd(struct Node** pHead, int iData)
{
struct Node* pTemp = (struct Node*)malloc(sizeof(struct Node));
if (pTemp != NULL)
{
// 节点成员赋值,每一个成员都要赋值
pTemp->iData = iData;
// 尤其是pTemp->pNext结点一定要赋值为空,会影响到后面的链表的操作
pTemp->pNext = NULL;
// 连接
if (*pHead == NULL) // 如果之前指针为空,则添加的就是头指针
{
*pHead = pTemp;
}
else // 如果之前指针不为空,添加的就要连到后面,通过循环找到尾
{
struct Node* pt = *pHead; //定义一个临时的中间变量指向头
while (pt->pNext != NULL) //找尾,循环到空的时候是尾
{
pt = pt->pNext; //因为要对pt进行从新赋值,所以要使用一个中间变量,否则记录的头指针就没了
}
pt->pNext = pTemp; //当pt->pNext等于NULL时,这是pt为最后一项。
}
}
}
1.5 链表的中间添加
// 中间添加
void AddToMiddle(struct Node** pHead, struct Node** pEnd, int Index, int iData)
{
// 创建结点,用新创建的结点来装形参
struct Node* pTemp = (struct Node*)malloc(sizeof(struct Node));
// 节点成员赋值
if (pTemp != NULL)
{
// 新结点装上形参后连接
pTemp->iData = iData;
pTemp->pNext = NULL; // 尾结点赋值成空很重要
// 根据下标查找结点
if (Index == 0) // 如果下标=0,添加到头部
{
AddToHead(pHead, pEnd, iData);
}
else // 根据下标查找结点
{
struct Node* pTemp = FindByIndex(*pHead, Index);
{
if (pTemp != NULL)
{
// 申请临时空间
struct Node* pT = (struct Node*)malloc(sizeof(struct Node));
if (pT != NULL)
{
// 节点赋值
pT->iData = iData;
pT->pNext = NULL;
// 连接上,先连后断
pT->pNext = pTemp->pNext;
pTemp->pNext = pT;
}
}
}
}
}
}
2.删除元素
删除元素的平均复杂度:O(n)
2.1 顺序链表的删除
// 删除尾
// 数量减一
void ShanChuWei(struct DongShuZu* pShuZu)
{
if (NULL == pShuZu)
{
printf("参数错误");
return;
}
pShuZu->iShuLiang--;
}
// 删除全部
// 数量设置为0
void ShanChuQuanBu(struct DongShuZu* pShuZu)
{
if (NULL == pShuZu)
{
printf("参数错误");
return;
}
pShuZu->iShuLiang = 0;
}
// 删除全部并清除空间
// 数量、容量都设置为零;释放头指针地址;头指针设置为NULL
void Qingkong(struct DongShuZu* pShuZu)
{
if (NULL == pShuZu)
{
printf("参数错误");
return;
}
pShuZu->iShuLiang = 0;
pShuZu->iRongLiang = 0;
free(pShuZu->pShuZuTou);
pShuZu->pShuZuTou = NULL;
}
// 删除中间元素
void ShanChuZhongJian(struct DongShuZu* pShuZu, int iXiaBiao)
{
if (NULL == pShuZu)
{
printf("参数错误");
return;
}
// 后面往前移
for (unsigned int i = iXiaBiao - 1; i < pShuZu->iShuLiang; i++)
{
pShuZu->pShuZuTou[i] = pShuZu->pShuZuTou[i + 1];
}
pShuZu->iShuLiang--;
}
// 将数据输出
void ShuChu(struct DongShuZu* pShuZu)
{
//参数检验,如果参数是空程序就为异常,参数有指针的都要进行参数检验
if (NULL == pShuZu)
{
printf("参数错误");
return;
}
printf("容量:%u,数量:%u\n", pShuZu->iRongLiang, pShuZu->iShuLiang);
printf("数据:");
for (unsigned int i = 0; i < pShuZu->iShuLiang; i++)
{
printf("%d ", pShuZu->pShuZuTou[i]);
}
printf("\n");
}
# include<stdio.h>
// 定义结构体
struct DongShuZu
{
int* pShuZuTou;
unsigned int iRongLiang;
unsigned int iShuLiang;
};
// 结构体初始化
void ChuShiHua(struct DongShuZu* pShuZu);
// 自动扩容
void ZengJia(struct DongShuZu* pShuZu, int iShuJu);
// 删除尾
// 数量减一
void ShanChuWei(struct DongShuZu* pShuZu);
// 删除全部
// 数量设置为0
void ShanChuQuanBu(struct DongShuZu* pShuZu);
// 删除全部并清除空间
// 数量、容量都设置为零;释放头指针地址;头指针设置为NULL
void Qingkong(struct DongShuZu* pShuZu);
// 删除中间元素
void ShanChuZhongJian(struct DongShuZu* pShuZu, int iXiaBiao);
// 将数据输出
void ShuChu(struct DongShuZu* pShuZu);
int main(void)
{
struct DongShuZu stShuZu;
ChuShiHua(&stShuZu);
ZengJia(&stShuZu, 1);
ZengJia(&stShuZu, 2);
ZengJia(&stShuZu, 3);
ZengJia(&stShuZu, 4);
ZengJia(&stShuZu, 5);
ZengJia(&stShuZu, 6);
ZengJia(&stShuZu, 7);
ZengJia(&stShuZu, 8);
ZengJia(&stShuZu, 9);
ShuChu(&stShuZu);
ShanChuWei(&stShuZu);
ShuChu(&stShuZu);
ShanChuZhongJian(&stShuZu, 3);
ShuChu(&stShuZu);
ShanChuQuanBu(&stShuZu);
ShuChu(&stShuZu);
Qingkong(&stShuZu);
ShuChu(&stShuZu);
}
// 结构体初始化
void ChuShiHua(struct DongShuZu* pShuZu)
{
pShuZu->iRongLiang = 5;
pShuZu->pShuZuTou = malloc(sizeof(int) * pShuZu->iRongLiang);
pShuZu->iShuLiang = 0;
}
// 自动扩容
void ZengJia(struct DongShuZu* pShuZu, int iShuJu)
{
if (NULL == pShuZu)
{
printf("参数错误");
return;
}
if (pShuZu->iRongLiang == pShuZu->iShuLiang)
{
pShuZu->iRongLiang += 5;
int* pTemp = malloc(sizeof(int) * pShuZu->iRongLiang);
for (unsigned int i = 0; i < pShuZu->iRongLiang; i++)
{
pTemp[i] = pShuZu->pShuZuTou[i];
}
free(pShuZu->pShuZuTou);
pShuZu->pShuZuTou = pTemp;
}
pShuZu->pShuZuTou[pShuZu->iShuLiang] = iShuJu;
pShuZu->iShuLiang++;
}
// 删除尾
void ShanChuWei(struct DongShuZu* pShuZu)
{
if (NULL == pShuZu)
{
printf("参数错误");
return;
}
pShuZu->iShuLiang--;
}
// 删除全部
void ShanChuQuanBu(struct DongShuZu* pShuZu)
{
if (NULL == pShuZu)
{
printf("参数错误");
return;
}
pShuZu->iShuLiang = 0;
}
// 删除全部并清除空间
void Qingkong(struct DongShuZu* pShuZu)
{
if (NULL == pShuZu)
{
printf("参数错误");
return;
}
pShuZu->iShuLiang = 0;
pShuZu->iRongLiang = 0;
free(pShuZu->pShuZuTou);
pShuZu->pShuZuTou = NULL;
}
// 删除中间元素
void ShanChuZhongJian(struct DongShuZu* pShuZu, int iXiaBiao)
{
if (NULL == pShuZu)
{
printf("参数错误");
return;
}
// 后面往前移
for (unsigned int i = iXiaBiao - 1; i < pShuZu->iShuLiang; i++)
{
pShuZu->pShuZuTou[i] = pShuZu->pShuZuTou[i + 1];
}
pShuZu->iShuLiang--;
}
// 将数据输出
void ShuChu(struct DongShuZu* pShuZu)
{
//参数检验,如果参数是空程序就为异常,参数有指针的都要进行参数检验
if (NULL == pShuZu)
{
printf("参数错误");
return;
}
printf("容量:%u,数量:%u\n", pShuZu->iRongLiang, pShuZu->iShuLiang);
printf("数据:");
for (unsigned int i = 0; i < pShuZu->iShuLiang; i++)
{
printf("%d ", pShuZu->pShuZuTou[i]);
}
printf("\n");
}
2.2 链式链表的删除
链式链表头删除
// 链式链表头删除
void DeleteHead(struct Node** pHead, struct Node** pEnd)
{
if (*pHead == NULL)
{
return;
}
if ((*pHead)->pNext == NULL) //* pHea == *pEnd,此时只有一个结点,直接释放
{
free(*pHead);
}
else
{
struct Node* pT = *pHead; //申请一个结点来装要删除的头结点
*pHead = (*pHead)->pNext; //头结点设置为她的下一个结点
free(pT); // 释放pT就相当于释放了原来的头结点,因为pT装的是原头结点
}
}
链式链表尾删除
- 循环找到倒数第二个结点
- free最后一个结点
- 新的尾指针(即原来倒数第二个节点)的下一个结点设置为NULL
// 链式链表尾删除
void DeleteEnd(struct Node** pHead, struct Node** pEnd)
{
if (*pHead == NULL)
{
return;
}
if ((*pHead)->pNext == NULL) //* pHea == *pEnd,此时只有一个结点,直接释放,但是要把下一个节点设置为NULL
{
free(*pHead); //释放结点
*pHead = NULL;
*pEnd = NULL;
}
else
{
// 找到倒数第二个节点,目的是为了把最后一个节点的下一个设置为NULL
struct Node* pT = *pHead; //先定义一个中间变量来装要删除的头结点
while (pT->pNext != *pEnd) // 当pT->pNext为*pEnd的时候,pT为倒数第二个节点
{
pT = pT->pNext;
}
// 找到之后
free(*pEnd); // 释放尾,而不是释放pT
*pEnd = pT; //再把尾结点设置为找到的倒数第二个结点
(*pEnd)->pNext = NULL; // 最重要的是把新的pEnd->pNext设置为NULL
}
}
链式链表中间删除
// 链式链表删除指定元素
void DeleteMiddle(struct Node** pHead, struct Node** pEnd, int iData)
{
if (*pHead == NULL)
{
return;
}
// 判断头尾指针是否是指定数据,如果是,直接调用头删除,尾删除
if ((*pHead)->iValue == iData)
{
DeleteHead(pHead, pEnd);
}
else if ((*pEnd)->iValue == iData)
{
DeleteEnd(pHead, pEnd);
}
else
{
struct Node* pTemp = *pHead; //一定要新创建一个结点来装头结点来进行循环查找,否则头指针可能会被修改
// 循环找数据结点
while (pTemp->pNext != NULL)
{
if (pTemp->pNext->iValue == iData)
{
break;
}
pTemp = pTemp->pNext;
}
if (pTemp->pNext != NULL)
{
struct Node* pT = pTemp->pNext; //记录要删除的结点,把pT这职位要删除结点的下一个结点
pTemp->pNext = pT->pNext; // 这样就把pT结点给抠出来了
free(pT);
}
else
{
printf("节点中无数据:%d\n",iData);
}
}
}
3. 修改元素(插入、修改,替换)
3.1 顺序链表的插入
插入元素需要把插入点处的坐标,以及后面的元素向后移:
插入算法平均复杂的:O(n)
// 插入数据函数
void ChaRu(struct Dongshuzu* pShuzu, int iShuJu, unsigned int iXiaBiao)
{
//参数检验,如果参数是空程序就为异常,参数有指针的都要进行参数检验
if (NULL == pShuzu)
{
printf("参数错误");
return;
}
//当下表>容量的时候,把该元素添加到最后
if (pShuzu->iRongliang == pShuzu->iShuliang) // 当容量==数量的时候需要扩容
{
// 容量变大
pShuzu->iRongliang += 10;
// 申请空间
int* pTemp = (unsigned int*)malloc(sizeof(unsigned int) * pShuzu->iRongliang);
// 将源数据复制进新空间
for (unsigned int i = 0; i < pShuzu->iRongliang; i++)
{
pTemp[i] = pShuzu->pShuzutou[i];
}
// 将源空间释放
free(pShuzu->pShuzutou);
// 将数组头指针指向新空间
pShuzu->pShuzutou = pTemp;
}
//当下标过大
if (iXiaBiao > pShuzu->iShuliang)
{
iXiaBiao = pShuzu->pShuzutou[pShuzu->iShuliang];
}
//向后挪
for (unsigned int i = pShuzu->iShuliang; i >= iXiaBiao; i--)
{
pShuzu->pShuzutou[i] = pShuzu->pShuzutou[i - 1];
}
// 数据插入到置定位是
pShuzu->pShuzutou[iXiaBiao] = iShuJu;
// 数据量++
pShuzu->iShuliang++;
}
# include<stdio.h>
# include<string.h>
# include<malloc.h>
struct Dongshuzu
{
int* pShuzutou; // 首地址
unsigned int iRongliang; // 容量
unsigned int iShuliang; //已存储的数量
};
// 初始化函数
void ChuShiHua(struct Dongshuzu* pShuzu)
{
pShuzu->iRongliang = 5; //设置初始容量
pShuzu->pShuzutou = malloc(sizeof(int) * pShuzu->iRongliang); //为设置的初始容量申请空间
pShuzu->iShuliang = 0; // 初始时已存储数量为0
}
// 扩容函数
void ZengJia(struct Dongshuzu* pShuzu, int iShuJu)
{
//参数检验,如果参数是空程序就为异常,参数有指针的都要进行参数检验
if (NULL == pShuzu)
{
printf("参数错误");
return;
}
if (pShuzu->iRongliang == pShuzu->iShuliang) // 当容量==数量的时候需要扩容
{
// 容量变大
pShuzu->iRongliang += 10;
// 申请空间
int* pTemp = (unsigned int*)malloc(sizeof(unsigned int) * pShuzu->iRongliang);
// 将源数据复制进新空间
for (unsigned int i = 0; i < pShuzu->iRongliang; i++)
{
pTemp[i] = pShuzu->pShuzutou[i];
}
// 将源空间释放
free ( pShuzu -> pShuzutou ) ;
// 将数组头指针指向新空间
pShuzu->pShuzutou = pTemp;
}
//将数据装进去
pShuzu->pShuzutou[pShuzu->iShuliang] = iShuJu; // 数字头[数量]数量的初始值为0
// 与存储数据量++
pShuzu->iShuliang++;
}
// 插入数据函数
void ChaRu(struct Dongshuzu* pShuzu, int iShuJu, unsigned int iXiaBiao)
{
//参数检验,如果参数是空程序就为异常,参数有指针的都要进行参数检验
if (NULL == pShuzu)
{
printf("参数错误");
return;
}
//当下表>容量的时候,把该元素添加到最后
if (pShuzu->iRongliang == pShuzu->iShuliang) // 当容量==数量的时候需要扩容
{
// 容量变大
pShuzu->iRongliang += 10;
// 申请空间
int* pTemp = (unsigned int*)malloc(sizeof(unsigned int) * pShuzu->iRongliang);
// 将源数据复制进新空间
for (unsigned int i = 0; i < pShuzu->iRongliang; i++)
{
pTemp[i] = pShuzu->pShuzutou[i];
}
// 将源空间释放
free(pShuzu->pShuzutou);
// 将数组头指针指向新空间
pShuzu->pShuzutou = pTemp;
}
//当下标过大
if (iXiaBiao > pShuzu->iShuliang)
{
iXiaBiao = pShuzu->pShuzutou[pShuzu->iShuliang];
}
//向后挪
for (unsigned int i = pShuzu->iShuliang; i >= iXiaBiao; i--)
{
pShuzu->pShuzutou[i] = pShuzu->pShuzutou[i - 1];
}
// 数据插入到置定位是
pShuzu->pShuzutou[iXiaBiao] = iShuJu;
// 数据量++
pShuzu->iShuliang++;
}
// 将数据输出
void ShuChu(struct Dongshuzu* stshuzu)
{
//参数检验,如果参数是空程序就为异常,参数有指针的都要进行参数检验
if (NULL == stshuzu)
{
printf("参数错误");
return;
}
printf("容量:%u,数量:%u\n", stshuzu->iRongliang, stshuzu->iShuliang);
printf("数据:");
for (unsigned int i = 0; i < stshuzu->iShuliang; i++)
{
printf("%d ", stshuzu->pShuzutou[i]);
}
}
int main(void)
{
struct Dongshuzu stshuzu;
ChuShiHua(&stshuzu);
ZengJia(&stshuzu, 1);
ZengJia(&stshuzu, 2);
ZengJia(&stshuzu, 3);
ZengJia(&stshuzu, 4);
ChaRu(&stshuzu, 34, 7);
ChaRu(&stshuzu, 34, 7);
ChaRu(&stshuzu, 34, 7);
ChaRu(&stshuzu, 34, 7);
ShuChu(&stshuzu);
free(stshuzu.pShuzutou);
return 0;
}
3.2 修改元素
// 修改指定数据(只修改第一个)
void ChangeByData(struct Node* pHead, int iData1, int iData2)
{
struct Node* pTemp = FindByData(pHead, iData1);
if (pTemp != NULL)
{
pTemp->iValue = iData2;
}
}
// 修改替换全部的指定数据
void ChangeALLData(struct Node* pHead, int iData1, int iData2)
{
if (pHead == NULL)
{
printf("输入节点有问题\n");
return;
}
// 第一次找到
struct Node* pRes = FindByData(pHead, iData1);
if (pRes == NULL)
{
printf("查无此节点\n");
}
else
{
pRes->iValue = iData2;
}
// 查找接下来的数据
while (pRes != NULL)
{
pRes = FindByData(pHead, iData1);
if (pRes != NULL)
{
pRes->iValue = iData2;
}
}
return;
}
// 修改指定下标数据
void ChangeByIndex(struct Node* pHead, int index, int iData2)
{
struct Node* pTemp = FindByIndex(pHead, 2);
if (pTemp != NULL)
{
pTemp->iValue = iData2;
}
}
4.查找数据
// 根据数据查找结点
int FindByData(struct Node* pHead, int iData)
{
while (pHead != NULL)
{
if (pHead->iValue == iData)
{
return pHead;
}
pHead = pHead->pNext;
}
return NULL;
}
//根据下标查找结点
int FindByIndex(struct Node* pHead, int iIndex)
{
int iNum = 1; // 下标要从1开始,链表下标没有0
while (pHead != NULL)
{
if (iIndex == iNum)
{
return pHead;
}
iNum++;
pHead = pHead->pNext;
}
return NULL;
}
// 根据数据查找结点
// 根据下表查找结点
# include <stdio.h>
struct Node
{
int iValue; //数据
struct Node* pNext; // 下一个结点地址
};
// 遍历数据
void Look(struct Node* pHead);
// 查找数据
int FindByData(struct Node* pHead, int iData);
//根据下标查找结点
int FindByIndex(struct Node* pHead, int iIndex);
//展示输出
void ShouData(struct Node* pHead);
int main(void)
{
struct Node a = { 4,NULL },
b = { 7,NULL },
c = { 9,NULL },
d = { 2,NULL };
a.pNext = &b;
b.pNext = &c;
c.pNext = &d;
Look(&a);
//查找数据
struct Node* pFind = FindByData(&a, 8);
ShouData(pFind);
// 根据下表查找结点
struct Node* pIndex = FindByIndex(&a, 2);
ShouData(pIndex);
system("pause>0");
return 0;
}
// 根据数据查找结点
int FindByData(struct Node* pHead, int iData)
{
while (pHead != NULL)
{
if (pHead->iValue == iData)
{
return pHead;
}
pHead = pHead->pNext;
}
return NULL;
}
//根据下标查找结点
int FindByIndex(struct Node* pHead, int iIndex)
{
int iNum = 1; // 下标要从1开始,链表下标没有0
while (pHead != NULL)
{
if (iIndex == iNum)
{
return pHead;
}
iNum++;
pHead = pHead->pNext;
}
return NULL;
}
// 遍历数据
void Look(struct Node* pHead)
{
// 遍历列表的循环
while (pHead != NULL)
{
printf("%d ", pHead->iValue);
pHead = pHead->pNext;
}
printf("\n");
}
//展示输出
void ShouData(struct Node* pHead)
{
if (pHead == NULL)
{
printf("查无结点\n");
}
else
{
printf("查到此结点:%d\n", pHead->iValue);
}
}