// 倒叙打印链表
void ReversePrint(SListNode *pFirst);
// 逆置链表
SListNode * ReverseList(SListNode *pFirst);
// 删除非尾无头链表
void RemoveNodeNotTail(SListNode *pos);
// 无头链表前插入
void InsertNoHead(SListNode *pos, int data);
/*
约瑟夫环
*/
SListNode * JocephCircle(SListNode *pFirst, int k);
// 冒泡排序
void BubbleSort(SListNode *pFirst);
// 合并两个有序链表
SListNode * MergeOrderedList(SListNode *p1First, SListNode *p2First);
// 遍历一次,找到中间结点
SListNode * FindMid(SListNode *pFirst);
// 遍历一次,找到倒数第 k 个结点(k从1开始)
SListNode * FindK(SListNode *pFirst, int k);
// 遍历一次,删除倒数第 k 个结点(k从1开始),不能用替换删除法
void RemoveK(SListNode *pFirst, int k)
void ReversePrint(SListNode *pFirst);
// 逆置链表
SListNode * ReverseList(SListNode *pFirst);
// 删除非尾无头链表
void RemoveNodeNotTail(SListNode *pos);
// 无头链表前插入
void InsertNoHead(SListNode *pos, int data);
/*
约瑟夫环
*/
SListNode * JocephCircle(SListNode *pFirst, int k);
// 冒泡排序
void BubbleSort(SListNode *pFirst);
// 合并两个有序链表
SListNode * MergeOrderedList(SListNode *p1First, SListNode *p2First);
// 遍历一次,找到中间结点
SListNode * FindMid(SListNode *pFirst);
// 遍历一次,找到倒数第 k 个结点(k从1开始)
SListNode * FindK(SListNode *pFirst, int k);
// 遍历一次,删除倒数第 k 个结点(k从1开始),不能用替换删除法
void RemoveK(SListNode *pFirst, int k)
引入单链表操作可见:单链表操作
#pragma once//防止头文件重定义
#include<stdio.h>
#include<Windows.h>
#include<assert.h>
typedef int DataType;
typedef struct CLinkList{
struct CLinkList *pNext;
struct CLinkList *pRandom;
DataType data;
}CLinkList;
#include"sLinkList.h"
#include"ComplexLinkList.h"
//从尾到头打印单链表(不带头、无循环)
//方法1:每次遍历找出pEnd
void PrintR(SLinkListNode *pFirst)
{
SLinkListNode *pNode, *pEnd = NULL;
pNode = pFirst;
while (pEnd != pFirst){
while (pNode->pNext != pEnd){
pNode = pNode->pNext;
}
pEnd = pNode;
printf("%d -> ", pNode->data);
pNode = pFirst;
}
printf("NULL\n");
}
//方法2:递归
void PrintD(SLinkListNode *pNode)
{
if (pNode->pNext){
PrintD(pNode->pNext);
}
printf("%d ", pNode->data);
}
//逆置单链表
SLinkListNode * ReverseList(SLinkListNode *pFirst)
{
//方法1:原链表头删+新链表头插
/*SLinkListNode *pNewFirst = NULL;
SLinkListNode *pNode;
pNode = pFirst;
while (pNode){
SLinkListPushFront(&pNewFirst, pNode->data);
pNode = pNode->pNext;
PopFront(&pFirst);
}
return pNewFirst;*/
//方法2:三个指针遍历
SLinkListNode *pre = NULL;
SLinkListNode *pNode = pFirst;
SLinkListNode *next = pNode->pNext;
while (pNode){
pNode->pNext = pre;
pre = pNode;
pNode = next;
if (next){
next = next->pNext;
}
else{
next = NULL;
}
}
return pre;
}
//删除一个无头单链表的非尾结点(不能遍历链表)
void DeleteNode(SLinkListNode *pPos)
{
//将pPos的pNext的data赋给pPos结点的data
//删除pPos的后一个结点
SLinkListNode *pNode;
pPos->data = pPos->pNext->data;
pNode = pPos->pNext->pNext;
free(pPos->pNext);
pPos->pNext = pNode;
}
//在无头单链表的一个节点前插入一个节点(不能遍历链表)
void InsertNode(SLinkListNode *pPos, DataType data)
{
//方法原理同上
//在当前节点位置的后面插入一个节点,交换data
SLinkListNode *pNewNode = CreatNewNode(data);
pNewNode->data = pPos->data;
pNewNode->pNext = pPos->pNext;
pPos->pNext = pNewNode;
pPos->data = data;
}
//合并两个有序链表,合并后依然有序
SLinkListNode * MergeSort(SLinkListNode *List1, SLinkListNode *List2)
{
SLinkListNode *pNode1 = List1;
SLinkListNode *pNode2 = List2;
SLinkListNode *pNewFirst = NULL;
while (pNode1 != NULL && pNode2 != NULL){
if (pNode1->data < pNode2->data){
SLinkListPushBack(&pNewFirst, pNode1->data);
pNode1 = pNode1->pNext;
}
else if (pNode1->data > pNode2->data){
SLinkListPushBack(&pNewFirst, pNode2->data);
pNode2 = pNode2->pNext;
}
else{
SLinkListPushBack(&pNewFirst, pNode1->data);
pNode1 = pNode1->pNext;
}
}
if (pNode1){
while (pNode1){
SLinkListPushBack(&pNewFirst, pNode1->data);
pNode1 = pNode1->pNext;
}
}
else{
while (pNode2){
SLinkListPushBack(&pNewFirst, pNode2->data);
pNode2 = pNode2->pNext;
}
}
return pNewFirst;
}
//求已排序的两个链表中相同的数据
void GetSameSet(SLinkListNode *List1, SLinkListNode *List2)
{
if (List1 == NULL || List2 == NULL){
printf("Null");
return;
}
SLinkListNode *pNode1 = List1;
SLinkListNode *pNode2 = List2;
while (pNode1 && pNode2){
if (pNode1->data == pNode2->data){
printf("%d ", pNode1->data);
pNode1 = pNode1->pNext;
pNode2 = pNode2->pNext;
continue;
}
else if (pNode1->data < pNode2->data){
pNode1 = pNode1->pNext;
}
else{
pNode2 = pNode2->pNext;
}
}
}
//单链表实现约瑟夫环
SLinkListNode * JosephCircle(SLinkListNode *pFirst, int num)
{
//单链表形成环
assert(pFirst);
SLinkListNode *pNode = pFirst;
while (pNode->pNext){
pNode = pNode->pNext;
}
pNode->pNext = pFirst;
SLinkListNode *pDNode = pFirst;
SLinkListNode *pPreNode = pDNode;
//根据num删除结点
while (pPreNode->pNext != pPreNode){
for (int i = 0; i < num; i++){
pPreNode = pDNode;
pDNode = pDNode->pNext;
}
pPreNode->pNext = pDNode->pNext;
free(pDNode);
pDNode = pPreNode->pNext;
}
return pPreNode;
}
//查找单链表的中间节点,要求只能遍历一次单链表
SLinkListNode * FindMiddle(SLinkListNode *pFirst)
{
//快慢指针,块指针是慢指针的二倍,快指针走到末尾,慢指针就指向中间节点
assert(pFirst);
SLinkListNode *pFast = pFirst;
SLinkListNode *pSlow = pFirst;
while (pFast){
pSlow = pSlow->pNext;
pFast = pFast->pNext;
if (!pFast){
break;
}
pFast = pFast->pNext;
}
return pSlow;
}
//查找单链表的倒数第k个节点,要求只能遍历一次单链表
SLinkListNode * FindLastkNode(SLinkListNode *pFirst, int k)
{
//前后指针,两个相同的指针,相隔k个节点一次遍历
assert(pFirst);
SLinkListNode *pPre = pFirst;
SLinkListNode *pBack = pFirst;
for (int i = 0; i < k; i++){
pBack = pBack->pNext;
}
while (pBack){
pPre = pPre->pNext;
pBack = pBack->pNext;
}
return pPre;
}
//删除链表倒数第k个节点
SLinkListNode * DeteleLastkNode(SLinkListNode *pFirst, int k)
{
//前后指针,记住前指针的前一个指针
assert(pFirst);
if (k == 1){
PopBack(&pFirst);
}
else{
SLinkListNode *pPreD = pFirst;
SLinkListNode *pPre = pFirst;
SLinkListNode *pBack = pFirst;
for (int i = 0; i < k; i++){
pBack = pBack->pNext;
}
while (pBack){
pPreD = pPre;
pPre = pPre->pNext;
pBack = pBack->pNext;
}
pPreD->pNext = pPre->pNext;
free(pPre);
}
return pFirst;
}
//复杂链表的复制
CLinkList * CmpLinkListCopy(CLinkList *pCFirst)
{
/*
1、复制节点(复制date和pNext),将新节点放在老节点的后面
2、遍历老节点,赋值pRandom
3、将链表拆分
*/
assert(pCFirst);
CLinkList *pNode = NULL;
CLinkList *pNewNode = NULL;
for (pNode = pCFirst; pNode; pNode = pNode->pNext->pNext){
pNewNode = (CLinkList *)malloc(sizeof(CLinkList));
assert(pNewNode);
pNewNode->data = pNode->data;
pNewNode->pNext = pNode->pNext;
pNewNode->pRandom = NULL;
pNode->pNext = pNewNode;
}
CLinkList *oldRandom = NULL;
for (pNode = pCFirst; pNode; pNode = pNode->pNext->pNext){
pNewNode = pNode->pNext;
oldRandom = pNode->pRandom;
if (oldRandom){
pNewNode->pRandom = oldRandom->pNext;
}
}
CLinkList *pNewFirst = NULL;
for (pNode = pCFirst; pNode; pNode = pNode->pNext->pNext){
pNewNode = pNode->pNext;
pNode->pNext = pNewNode->pNext;
if (pNode->pNext != NULL){
pNewNode->pNext = pNode->pNext->pNext;
}
else{
pNewNode->pNext = NULL;
}
}
return pNewNode;
}
int main()
{
CLinkList *pCFirst = NULL;
/*SLinkListNode *pFirst = NULL;
SLinkListPushFront(&pFirst, 8);
SLinkListPushFront(&pFirst, 6);
SLinkListPushFront(&pFirst, 4);
SLinkListPushFront(&pFirst, 2);
SLinkListPushFront(&pFirst, 9);
SLinkListPushFront(&pFirst, 5);
Print(pFirst);*/
//Print(DeteleLastkNode(pFirst, 2));
//Print(FindLastkNode(pFirst, 3));
//Print(FindMiddle(pFirst));
//printf("%d\n", JosephCircle(pFirst, 4)->data);
/*SLinkListNode *pFirst1 = NULL;
SLinkListPushFront(&pFirst1, 7);
SLinkListPushFront(&pFirst1, 5);
SLinkListPushFront(&pFirst1, 4);
SLinkListPushFront(&pFirst1, 1);
Print(pFirst1);
Print(MergeSort(pFirst, pFirst1));
GetSameSet(pFirst, pFirst1);*/
//PrintR(pFirst);
//PrintD(pFirst);
//Print(ReverseList(pFirst));
//DeleteNode(pFirst->pNext);
/*InsertNode(pFirst->pNext, 8);
Print(pFirst);*/
system("pause");
return 0;
}