一、链表的查找
每次访问一个节点元素判断是否为要找的节点,符合条件返回该节点地址,到最后依旧没有找到符合条件的节点,返回NULL
linknode *find_linklist(linknode *phead, datatype tmpdata)
{
linknode *ptmpnode = NULL;
ptmpnode = phead->pnext;
while (ptmpnode != NULL)
{
if (ptmpnode->data == tmpdata)
{
return ptmpnode;
}
ptmpnode = ptmpnode->pnext;
}
return NULL;
}
二、 链表的修改
沿用遍历思想,找到符合条件的元素修改为新的值
int update_linklist(linknode *phead, datatype olddata, datatype newdata)
{
linknode *ptmpnode = NULL;
ptmpnode = phead->pnext;
while (ptmpnode != NULL)
{
if (ptmpnode->data == olddata)
{
ptmpnode->data = newdata;
}
ptmpnode = ptmpnode->pnext;
}
return 0;
}
三、链表的尾插
申请节点空间,将数据存放到节点中,将节点中地址赋值为NULL,找到最后一个节点,最后一个节点的pnext赋值为新申请节点
int insert_tail_linklist(linknode *phead, datatype tmpdata)
{
linknode *ptmpnode = NULL;
linknode *plastnode = NULL;
ptmpnode = malloc(sizeof(linknode));
if (NULL == ptmpnode)
{
perror("fail to malloc")
return -1;
}
ptmpnode->data = tmpdata;
ptmpnode->pnext = NULL;
plastnode = phead; //如果链表中只有头文件,此时为phead->pnext,下面将无法进行//必须为phead
while (plastnode->pnext != NULL)
{
plastnode = plastnode->pnext;
}
plastnode->pnext = ptmpnode;
return 0;
}
四、链表的销毁
定义两个指针pfreenode和ptmpnode都指向头节点,ptmpnode向后走,再释放pfreenode指向的节点,再将pfreenode指向ptmpnode指向的空间(需要用二级指针)
int destroy_linklist(linknode **pphead)
{
linknode *pfreenode = NULL;
linknode *ptmpnode = NULL;
ptmpnode = *pphead;
pfreenode = *pphead;
while (ptmpnode != NULL)
{
ptmpnode = ptmpnode->pnext;
free(pfreenode);
pfreenode = ptmpnode;
}
*pphead = NULL;
return 0;}
五、查找链表中间节点
快指针每次走2步,慢指针每次都1步;快指针走到末尾,慢指针走到中间,慢指针处就是中间节点
linknode *find_midnode(linknode *phead)
{
linknode *pslow = NULL;
linknode *pfast = NULL;
pslow = pfast = phead->pnext;
while (pfast != NULL)
{
pfast = pfast->pnext;
if (NULL == pfast)
{
break;
}
pfast = pfast->pnext;
if (NULL == pfast)
{
break;
}
pslow = pslow->pnext;
}
return pslow;
}
六、查找链表倒数第k个节点
快指针先走k步,慢指针和快指针每次同时走一步;快指针到达末尾,慢指针少走k步,即倒数第k个元素
linknode *find_last_kth_node(linknode *phead, int k)
{
int i = 0;
linknode *pfast = NULL;
linknode *pslow = NULL;pfast = phead->pnext;
for (i = 0; i < k && pfast != NULL; i++)
{
pfast = pfast->pnext;
}
if (NULL == pfast)
{
return NULL;
}
pslow = phead->pnext;
while (pfast != NULL)
{
pfast = pfast->pnext;
pslow = pslow->pnext;
}
return pslow;
}
七、 不知道头节点地址如何删除链表中间节点
将指针指向的下一个节点的值完全覆盖当前节点的值,释放下一个节点
int delete_linknode(linknode *ptmpnode)
{
linknode *pnextnode = NULL;
pnextnode = ptmpnode->pnext;
ptmpnode->data = pnextnode->data;
ptmpnode->pnext = pnextnode->pnext;
free(pnextnode);
return 0;
}
八、链表的倒置
将原链表断开,将所有的元素依次使用头插法插入即可实现
int reverse_linklist(linknode *phead)
{
linknode *pinsertnode = NULL;
linknode *ptmpnode = NULL;//将链表从头结点处断开
ptmpnode = phead->pnext;
phead->pnext = NULL;//依次将所有元素使用头插法插入链表中
while (ptmpnode != NULL)
{
pinsertnode = ptmpnode;
ptmpnode = ptmpnode->pnext;
pinsertnode->pnext = phead->pnext;
phead->pnext = pinsertnode;
}
return 0;
}
九、 链表的排序
1.冒泡排序
①定义两个指针,相邻两个元素比较
②指针循环向后走,直到ptmpnode2为NULL,即等于pend,循环停止
③pend赋值为tmpnode1的节点地址‘下一轮就可以少比1次
④循环将所有大的元素找到,剩余一个小的元素即可
int bubble_sort_linklist(linknode *phead)
{
linknode *ptmpnode1 = NULL;
linknode *ptmpnode2 = NULL;
linknode *pend = NULL;
datatype tmpdata;
if (NULL == phead->pnext || NULL == phead->pnext->pnext )
{
return 0;
}
while (1)
{
ptmpnode1 = phead->pnext;
ptmpnode2 = phead->pnext->pnext;
if (pend == ptmpnode2)
{
break;
}
while (ptmpnode2 != pend)
{
if (ptmpnode1->data > ptmpnode2->data)
{
tmpdata = ptmpnode1->data;
ptmpnode1->data = ptmpnode2->data;
ptmpnode2->data = tmpdata;
}
ptmpnode1 = ptmpnode1->pnext;
ptmpnode2 = ptmpnode2->pnext;
}
pend = ptmpnode1;}
return 0;
}
2.选择排序
pswapnode指向要交换的节点,pminnode假设的最小值,ptmpnode和后续节点比较,如果小的话就和pswapnode交换,pswapnode不断向后增加不断比较得到排序
int select_sort_linklist(linknode *phead)
{
linknode *pswapnode = NULL;
linknode *ptmpnode = NULL;
linknode *pminnode = NULL;
datatype tmpdata;
if (NULL == phead->pnext || NULL == phead->pnext->pnext)
{
return 0;
}
pswapnode = phead->pnext;
while (pswapnode->pnext != NULL)
{
pminnode = pswapnode;
ptmpnode = pswapnode->pnext;
while (ptmpnode != NULL)
{
if (ptmpnode->data < pminnode->data)
{
pminnode = ptmpnode;
}
ptmpnode = ptmpnode->pnext;
}
if (pswapnode != pminnode)
{
tmpdata = pswapnode->data;
pswapnode->data = pminnode->data;
pminnode->data = tmpdata;
}
pswapnode = pswapnode->pnext;
}
return 0;
}
十、 判断链表是否有环
1.先判断链表是否有环:定义两个指针,快指针(每次走2步)和慢指针(每次走1步),快指针 - 慢指针 == 环长即相遇,快指针和慢指针相等即为链表有环
2.环长为:定义一个指针从环相遇点开始走一圈,直到走该该节点为止;每走一个节点计数,最终可得到环长
3.入口位置:定义一个指针从相遇点开始每次走一步,定义一个指针从开头每次走一步,两个指针相遇的位置即为环入口位置
int circle_linklist(linknode *phead, int *pis_circle, int *pcirlen, linknode **ppnode)
{linknode *pfast = NULL;
linknode *pslow = NULL;
linknode *ptmpnode = NULL;
linknode *pstartnode = NULL;
int cnt = 1;
/* 判断是否有环 */
pfast = phead->pnext;
pslow = phead->pnext;
while (1)
{
pfast = pfast->pnext;
if (NULL == pfast)
{
break;
}
pfast = pfast->pnext;
if (NULL == pfast)
{
break;
}
pslow = pslow->pnext;
if (pfast == pslow)
{
break;
}
}
if (NULL == pfast)
{
*pis_circle = 0;
return 0;
}
else
{
*pis_circle = 1;
}/* 统计环长 */
ptmpnode = pslow->pnext;
while (ptmpnode != pslow)
{
cnt++;
ptmpnode = ptmpnode->pnext;
}
*pcirlen = cnt;/* 找到环入口 */
pstartnode = phead->pnext;
ptmpnode = pslow;
while (pstartnode != ptmpnode)
{
pstartnode = pstartnode->pnext;
ptmpnode = ptmpnode->pnext;
}*ppnode = ptmpnode;
return 0;
}

被折叠的 条评论
为什么被折叠?



