单链表的基本操作大全之C语言实现(二)
补充一些链表的操作,之前的基本操作点击下面的链接。
单链表的基本操作大全之C语言实现(一)
1. 递归打印链表
void show_linklist(PNODE *phead)
{
if(phead == NULL){
return;
}else{
printf("%d\t", phead->data);
show_linklist(phead->pnext);
//将此行放在printf的前面则递归打印倒置链表
}
}
2.链表快速排序
PNODE *divide_two_Qsort(PNODE *phead, PNODE *ptail)
{
int key = phead->data;
PNODE *p = phead;
PNODE *q = phead->pnext;
while(q != ptail){
if(q->data < key){
p = p->pnext;
int tmp;
tmp = p->data;
p->data = q->data;
q->data = tmp;
}
q = q->pnext;
}
int tmp = p->data;
p->data = phead->data;
phead->data = tmp;
return p;
}
void quicksort_linklist(PNODE *phead, PNODE *ptail)
{
if(phead != ptail){
PNODE *pmid = divide_two_Qsort(phead, ptail);
quicksort_linklist(phead, pmid);
quicksort_linklist(pmid->pnext, ptail);
}
}
3. 递归计算链表长度
int getlistlen_recursion(PNODE *phead)
{
if(phead == NULL)
return 0;
else
return 1+getlistlen_recursion(phead->pnext);
}
4.反转链表(非递归)
PNODE *invert_linklist(PNODE *phead)
{
if(phead == NULL || phead->pnext == NULL){
return phead;
}else{
PNODE *p = phead;
PNODE *q = NULL;
PNODE *r = NULL;
while(p != NULL){
q = p->pnext;//保存下一个节点
p->pnext = r;//让该节点指向上一个节点
r = p;//上一个节点走到当前节点
p = q;//当前节点走到下一个节点
}
return r;
}
}
5.反转链表(递归)
PNODE *invert_linklist_recursion(PNODE *phead)
{
if(phead == NULL || phead->pnext == NULL){
return phead;
}else{
PNODE *p = phead;//保存头节点
PNODE *q = p->pnext;//保存下一个节点
phead = invert_linklist_recursion(q);//递归到最后一个几点,返回转置后链表的地址
q->pnext = p;//让后面的节点指向前一个节点
p->pnext = NULL;//每次递归返回都赋值为空,最后一次返回将转置后的节点的pnext赋值为空
return phead;
}
}
6.合并两个有序链表(非递归)
PNODE *merge_linklist(PNODE *phead1, PNODE *phead2)
{
if(phead1 == NULL){
return phead2;
}else if(phead2 == NULL){
return phead1;
}
PNODE *phead = NULL;
if(phead1->data < phead2->data){
phead = phead1;
phead1 = phead1->pnext;
}else{
phead = phead2;
phead2 = phead2->pnext;
}//让phead找到最小的头节点
PNODE *pcur = phead;//要比较节点(phead1 或 phead2)的上一个节点
while(phead1 != NULL && phead2 != NULL){
if(phead1->data < phead2->data){
pcur->pnext = phead1;
pcur = phead1;
phead1 = phead1->pnext;
}else{
pcur->pnext = phead2;
pcur = phead2;
phead2 = phead2->pnext;
}
}
pcur->pnext = ((phead1 == NULL) ? phead2 : phead1);
return phead;
}
7.合并两个有序链表(递归)
PNODE *merge_linklist_recursion(PNODE *phead1, PNODE *phead2)
{
if(phead1 == NULL){
return phead2;
}else if(phead2 == NULL){
return phead1;
}
PNODE *phead = NULL;
if(phead1->data < phead2->data){
phead = phead1;
phead->pnext = merge_linklist_recursion(phead1->pnext, phead2);
}else{
phead = phead2;
phead->pnext = merge_linklist_recursion(phead1, phead2->pnext);
}
return phead;
}
8.找到链表中间节点
PNODE *find_midnode(PNODE *phead)
{
if(phead == NULL || phead->pnext == NULL){
return phead;
}
PNODE *p1 = phead;
PNODE *p2 = phead;
while(p2->pnext != NULL){
p1 = p1->pnext;//p1走一步
p2 = p2->pnext;
if(p2->pnext != NULL){
p2 = p2->pnext;//p2走两步
}
}
return p1;
}
9.判断链表是否有环
int is_circularlinklist(PNODE *phead)
{
if(phead == NULL || phead->pnext == NULL){
return 0;
}
PNODE *p1 = phead;
PNODE *p2 = phead;
while(p1 != NULL && p2 != NULL){
p2 = p2->pnext;
if(p1 == p2)
return 1;
p2 = p2->pnext;
p1 = p1->pnext;
}
return 0;
}
10.释放链表
void destory_linklist(PNODE *phead)
{
PNODE *ptmp;
while(phead != NULL){
ptmp = phead;
phead = phead->pnext;
free(ptmp);
ptmp = NULL;
}
}