版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yc1515707718/article/details/80406969
1.从尾到头打印单链表
通过递归找到最后一个节点输出,然后通过条件判断层层返回输出。
void ReversePrint(Slist* head) //从尾到头输出单链表
{
if (head == NULL)
{
return;
}
Slist* cur = head;
if (cur->next == NULL) //只有一个节点
{
printf("%d ", cur->data);
return;
}
ReversePrint(cur->next);
printf("%d ", cur->data);
}
2.删除一个无头单链表的非尾节点(不能遍历链表)
不能遍历链表说明找不到要删节点的前一个节点,不能常规删除,所以可以找到要删除节点的下一个节点ret,然后互换pos和ret的值,删除pos即可。
void DelListNode(Slist** pos) //删除一个无头单链表的非尾节点
{
if (*pos == NULL)
{
return;
}
if ((*pos)->next == NULL)
{
free(pos);
pos = NULL;
}
else
{
Slist* ret = (*pos)->next;
(*pos)->data = ret->data;
(*pos)->next = ret->next;
free(ret);
ret = NULL;
}
}
3.在无头单链表的一个节点前插入一个节点(不能遍历链表)
可以把要插入的节点插在pos的后边,然后交换这两个的值即可。
void PlistInsert(Slist **pos, DataType x) //在无头单链表的一个节点前插入一个节点(不能遍历链表)
{
if (*pos == NULL)
{
return;
}
else
{
Slist* cur = BuySlist(x);
cur->next = (*pos)->next;
(*pos)->next = cur;
swap(&(*pos)->data, &cur->data);
}
}
4.单链表实现约瑟夫环(JosephCircle)
int SListJosephCircle(Slist* head, int k)
{
if (head == NULL)
{
return -1;
}
if (head->next == NULL)
{
return head->data;
}
Slist* phead = head;
while (phead->next!=NULL) //成环
{
phead = phead->next;
}
phead->next = head;
//实现过程
Slist* p1 = head;
Slist* p2 = head;
Slist* cur = p1;
while (cur->next!=NULL)
{
int ret = k - 1;
while (ret--)
{
p1 = p2;
p2 = p2->next;
}
if (p1->next->next == p1) //剩下两个节点
{
free(p2);
p2 = NULL;
return p1->data;
}
Slist* tmp = p2;
p2 = p2->next;
free(tmp);
tmp = NULL;
p1->next = p2;
cur = p1;
}
return cur->data;
}
5.逆置/反转单链表
void reverse_list(Slist **pphead) //逆置/反转单链表
{
if (*pphead == NULL||(*pphead)->next==NULL)
{
return ;
}
Slist* p1 = *pphead;
Slist* p2 = p1->next;
Slist* p3 = p2->next;
p1->next = NULL;
while (p3!=NULL)
{
p2->next = p1;
p1 = p2;
p2 = p3;
p3 = p2->next;
}
p2->next = p1;
*pphead = p2;
}
6.单链表排序(冒泡排序&快速排序)
冒泡:
void bubble_sort(Slist **pphead) //冒泡排序
{
if (*pphead == NULL)
{
return;
}
int flag = 0;
Slist* tail = NULL;
while (tail != (*pphead)->next)
{
Slist* cur = *pphead;
while (cur->next != tail)
{
if (cur->data > (cur->next)->data)
{
flag = 1;
swap(&cur->data, &(cur->next)->data);
}
cur = cur->next;
}
tail = cur;
if (flag == 0) //已经有序
{
return;
}
}
}
选择:
void SeletSort(Slist** phead) //选择排序
{
if (*phead == NULL)
{
return;
}
Slist* p1 = *phead;
while (p1->next != NULL)
{
Slist* min = p1;
Slist* p2 = p1;
while (p2!=NULL)
{
if (p2->data <= min->data)
{
min = p2;
}
p2 = p2->next;
}
if (min != p1)
{
swap(&min->data, &p1->data);
}
p1 = p1->next;
}
}
7.合并两个有序链表,合并后依然有序
Slist* SListMerge(Slist* list1, Slist* list2) //合并两量表为有序
{
assert(list1&&list2);
Slist* p1 = list1;
Slist* p2 = list2;
Slist* list3 = NULL;
while (1)
{
if (p1->data <= p2->data)
{
ListPushback(&list3, p1->data);
p1 = p1->next;
}
if (p1 == NULL)
{
break;
}
if (p1->data > p2->data)
{
ListPushback(&list3, p2->data);
p2 = p2->next;
}
if (p2 == NULL)
{
break;
}
}
Slist* p3 = list3;
while(p3->next != NULL)
{
p3 = p3->next;
}
if (p1 == NULL)
{
p3->next = p2;
}
if (p2 == NULL)
{
p3->next = p1;;
}
return list3;
}
8.查找单链表的中间节点,要求只能遍历一次链表
void SListFindMidNode(Slist* list) //查找中间节点 已经过测试无bug
{
if (list == NULL) //没有节点
{
return;
}
if (list->next == NULL) //一个节点
{
printf("%d\n", list->data);
return;
}
Slist* p1 = list;
Slist* p2 = list;
while ( p2 != NULL && p2->next != NULL)
{
p2 = p2->next->next;
if (p2 == NULL)
{
break;
}
p1 = p1->next;
}
if (p2 == NULL) //偶数个节点
{
printf("%d %d\n", p1->data, p1->next->data);
return;
}
if (p2->next == NULL) //奇数个节点
{
printf("%d \n", p1->data );
return;
}
}
9.查找单链表的倒数第k个节点,要求只能遍历一次链表
void SListFindTailKNode(Slist* list, size_t k) //倒数第K个节点
{
if (list == NULL)
{
return;
}
Slist* p1 = list;
Slist* p2 = list;
while (k--)
{
p2 = p2->next;
}
while (p2 != NULL)
{
p2 = p2->next;
p1 = p1->next;
}
printf("%d\n", p1->data);
}
10.删除链表的倒数第K个结点
void SListFindTailKNode(Slist* list, size_t k) //倒数第K个节点
{
if (list == NULL)
{
return;
}
Slist* p1 = list;
Slist* p2 = list;
while (k--)
{
p2 = p2->next;
}
while (p2 != NULL)
{
p2 = p2->next;
p1 = p1->next;
}
printf("%d\n", p1->data);
}
void SListDeletTailKNode(Slist* list, size_t k) //删除倒数第K个节点
{
if (list == NULL)
{
return;
}
Slist* p1 = list;
Slist* pre = p1;
Slist* p2 = list;
while (k--)
{
p2 = p2->next;
}
while (p2 != NULL)
{
p2 = p2->next;
pre = p1;
p1 = p1->next;
}
DelListNode(&p1);
}