#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <string.h>
#include <assert.h>
typedef int DataType;
typedef struct ListNode{
DataType data;
struct ListNode *pNext;
} ListNode;
ListNode *NewSpace(DataType data)
{
ListNode *pNode = (ListNode *)malloc(sizeof(ListNode));
assert(pNode);
pNode->data = data;
pNode->pNext = NULL;
return pNode;
}
void ListInit(ListNode **pListHead)
{
(*pListHead) = NewSpace(-1);
(*pListHead)->pNext = NULL;
}
void InsertFront(ListNode **pListHead, DataType data)
{
assert(*pListHead);
ListNode *pNode = NewSpace(data);
if ((*pListHead)->data == -1){
(*pListHead)->data = data;
return;
}
pNode->pNext = (*pListHead);
(*pListHead) = pNode;
return;
}
void InsertBack(ListNode **pListHead, DataType data)
{
assert(*pListHead);
ListNode *pNode = NewSpace(data);
ListNode *pInsert = (*pListHead);
if ((*pListHead)->data == -1){
(*pListHead)->data = data;
return;
}
while (pInsert->pNext){
pInsert = pInsert->pNext;
}
pInsert->pNext = pNode;
}
//找第k个结点
ListNode *FindKthTotail(ListNode *pListHead, int k)
{
assert(pListHead);
int iTotal = 0;
int iFind = 0;
ListNode *pFind = pListHead;
while (pFind){
iTotal++;
pFind = pFind->pNext;
}
//printf("%d \n", iTotal);
iFind = iTotal - k + 1;
pFind = pListHead;
while (iFind--){
pFind = pFind->pNext;
}
printf("第%d个结点的值:%d 地址:%p\n", k, pFind->data, pFind);
return pFind;
}
//头删
void DelFront(ListNode **pListHead)
{
assert(*pListHead);
ListNode *pDel = (*pListHead);
(*pListHead) = (*pListHead)->pNext;
free(pDel);
pDel = NULL;
}
//尾删
void DelBack(ListNode **pListHead)
{
assert(*pListHead);
if ((*pListHead)->pNext == NULL){
free(*pListHead);
pListHead = NULL;
return;
}
ListNode *pDel = (*pListHead);
while (pDel->pNext->pNext){
pDel = pDel->pNext;
}
free(pDel->pNext);
pDel->pNext = NULL;
}
void SimpListPrint(ListNode *pListHead)
{
assert(pListHead);
ListNode *pPri = pListHead;
while (pPri){
printf("%-3d", pPri->data);
pPri = pPri->pNext;
}
printf("\n");
}
//删除一个无头单链表的非尾节点(不能遍历链表)
void DelPos(ListNode **pListHead, ListNode *pPos)
{
assert(*pListHead);
assert(pPos);
assert(pPos->pNext); //非尾
ListNode *pDel = pPos->pNext;
pPos->data = pDel->data;
pPos->pNext = pDel->pNext;
free(pDel);
pDel = NULL;
}
//在无头单链表的一个节点前插入一个节点(不能遍历链表)
void InsertPosFront(ListNode **pListHead, ListNode *pPos, DataType data)
{
//先插到这个结点后面,再交换
assert(*pListHead);
ListNode *pNode = NewSpace(data);
pNode->pNext = pPos->pNext;
pPos->pNext = pNode;
DataType tmp = *(&pPos->data);
*(&pPos->data) = *(&pNode->data);
*(&pNode->data) = tmp;
}
//单链表实现约瑟夫环(JosephCircle)
void JosephCircle(ListNode *pListHead, int k)
{
//这是一个环形链表
assert(pListHead);
ListNode *pList = pListHead;
ListNode *pPre = pListHead;
int i = k;
while (pList->pNext != pListHead){
i = k;
while (i--){
pPre = pList;
pList = pList->pNext;
}
pPre->pNext = pList->pNext;
free(pList);
pList = pPre->pNext;
}
}
//逆置/反转单链表
void Reverse(ListNode **pListHead)
{
//或者重新定义一个链表 从头遍历旧链表 每个节点用头插法插到新链表
assert(*pListHead);
ListNode *pNewList;
ListInit(&pNewList);
ListNode *pList = (*pListHead);
while (pList){
InsertFront(&pNewList, pList->data);
pList = pList->pNext;
}
free(*pListHead);
(*pListHead) = pNewList;
}
//单链表排序(冒泡排序&快速排序)
void Swap(DataType *a, DataType *b)
{
DataType tmp = *a;
*a = *b;
*b = tmp;
}
void ListBubbleSort(ListNode **pListHead)
{
assert(*pListHead);
int iTotal = 0;
ListNode *pSort_1 = (*pListHead);
ListNode *pSort_2 = (*pListHead)->pNext;
while (pSort_1){
iTotal++;
pSort_1 = pSort_1->pNext;
}
pSort_1 = (*pListHead);
for (pSort_1 = (*pListHead); pSort_1->pNext != NULL; pSort_1 = pSort_1->pNext){
for (pSort_2 = pSort_1->pNext; pSort_2 != NULL; pSort_2 = pSort_2->pNext){
if (pSort_1->data > pSort_2->data){
Swap(&pSort_1->data, &pSort_2->data);
}
}
}
}
//查找单链表的中间节点,要求只能遍历一次链表
void GetMid(ListNode *pListHead)
{
if (pListHead == NULL){
return;
}
ListNode *pSlow = pListHead;
ListNode *pFast = pListHead;
while (pFast->pNext->pNext){
pSlow = pSlow->pNext;
pFast = pFast->pNext->pNext;
}
printf("中间节点:%d \n", pSlow->data);
}
//查找单链表的倒数第k个节点,要求只能遍历一次
DataType GetKTotail(ListNode *pListHead, int k)
{
assert(pListHead);
int i = 0;
int total = 0;
ListNode *pFind = pListHead;
while (pFind){
total++;
pFind = pFind->pNext;
}
pFind = pListHead;
for (i = k; i < total; ++i){
pFind = pFind->pNext;
}
return pFind->data;
}
//删除链表的倒数第K个结点
//找到倒数第k+1个结点
void DelKthTotail(ListNode **pListHead, int k)
{
assert(*pListHead);
int i = 0;
int total = 0;
ListNode *pFind = *pListHead;
ListNode *pDel = *pListHead;
while (pFind){
total++;
pFind = pFind->pNext;
}
pFind = *pListHead;
for (i = k + 1; i < total; ++i){
pFind = pFind->pNext;
}
pDel = pFind->pNext;
pFind->pNext = pDel->pNext;
free(pDel);
}
int main()
{
ListNode *SimpList;
ListInit(&SimpList);
InsertFront(&SimpList, 3);
InsertFront(&SimpList, 4);
InsertFront(&SimpList, 5);
InsertFront(&SimpList, 6);
InsertFront(&SimpList, 7);
InsertBack(&SimpList, 98);
InsertBack(&SimpList, 76);
InsertBack(&SimpList, 54);
InsertBack(&SimpList, 32);
InsertBack(&SimpList, 10);
FindKthTotail(SimpList, 6); //查找第k个结点
SimpListPrint(SimpList);
DelFront(&SimpList);
SimpListPrint(SimpList);
DelBack(&SimpList);
SimpListPrint(SimpList);
Reverse(&SimpList);
SimpListPrint(SimpList);
ListBubbleSort(&SimpList);
SimpListPrint(SimpList);
GetMid(SimpList);
int k = 1;
printf("倒数第%d个结点是:%d \n", k, GetKTotail(SimpList, k));
DelKthTotail(&SimpList, 5);
SimpListPrint(SimpList);
return 0;
}