list.h
#define _CRT_SECURE_NO_WARNINGS 1
#ifndef __LIST_H__
#define __LIST_H__
//#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
typedef struct Node
{
int data;
struct Node *next;
}Node, *pList;
//初始化
void InitList(pList plsit);
void InsertTail(pList plist, int val);
Node *LastKNode(pList plist, int k);
Node* reverse(pList plist);
void Show(pList plist);
void Show1(pList plist);
int Return(pList plist);
//头插
//尾插
//打印
//任意位置插入
//删除
//查找
Node *FindMidleNode(pList plist);
void reverseHead(pList plist);
#endif //__LIST_H__
list.c
#include "list.h"
void InitList(pList plsit)
{
assert(plsit != NULL);
plsit->data = 0;
plsit->next = NULL;
}
//得到一个节点
Node *GetNode(int val)
{
Node* pGet = (Node *)malloc(sizeof(Node));
assert(pGet != NULL);
pGet->data = val;
pGet->next = NULL;
return pGet;
}
//头插 plist: 头结点的地址
void InsertHead(pList plist, int val)//55
{
Node *pGet = GetNode(val);
assert(plist != NULL);
pGet->next = plist->next;
plist->next = pGet;
}
void InsertTail(pList plist, int val)
{
Node *pGet = GetNode(val);
Node*p = plist;
while (p->next != NULL)
{
p = p->next;
}
p->next = pGet;
}
Node *LastKNode(pList plist, int k)
{
int i;
Node *p = plist;
Node *q = plist;
if (k < 0)
{
return NULL;
}
for (i = 0; i <= k - 2; i++)
{
if (q != NULL)
q = q->next;
else
return NULL;
}
while (q != NULL)
{
p = p->next;
q = q->next;
}
return p;
//1、让一个指针先走K-1步
//2.两个指针同时走,后面一个指针走到了NULL时,p指正好走了K步
}
void Show(pList plist)
{
Node* p = plist->next;
while (p != NULL)
{
printf("%d ", p->data);
p = p->next;
}
}
Node *FindMidleNode(pList plist) //定义2指针,一个走2步一个走一步,当走2步的指针为NULL时,走一步的指针指向的就是中间节点
{
Node *pFast = plist;
Node *pSlow = plist;
while (pFast != NULL)
{
pSlow = pSlow->next;
if (pFast->next != NULL) //走2步的指针走一步判断一步,不然可能走一步时它的指针为NULL继续走,导致BUG
{
pFast = pFast->next;
}
else
{
return pSlow;
}
if (pFast->next != NULL)
{
pFast = pFast->next;
}
else
{
return pSlow;
}
}
}
void reverseHead(pList plist)
{
Node *pCur = plist->next;
Node *pCurN = plist->next;
plist->next = NULL;
while(pCurN != NULL)
{
pCurN = pCur->next;
pCur->next = plist->next; //先绑后面,不然会导致数据丢失
plist->next = pCur;
pCur = pCurN;
}
}
Node* reverse(pList plist)
{
Node* pCur = plist->next; //pCur当前位置,pCur用来记录下一个位置,prev记录前一个节点的位置
Node* pCurN = plist->next;
Node *prev = plist;
prev->next = NULL;
while (pCurN != NULL)
{
pCurN = pCur->next;
pCur->next = prev;
prev = pCur;
pCur = pCurN;
}
return prev;
}
void Show1(pList plist)
{
Node* p = plist;
while (p->next != NULL)
{
printf("%d ", p->data);
p = p->next;
}
}
int Return(pList plist)
{
Node* w = plist->next; //w从头开始走,到达中间节点停止
Node *p=FindMidleNode(plist); //找到中间节点,用p记录下来
Node *q = reverse(p); //将中间节点之后的单链表逆置
while ( w!=p && q!=p )
{
if (w->data == q->data)
{
w = w->next;
q = q->next;
}
else
{
return 0;
}
return 1;
}
}
主函数main.c文件
#include "list.h"
int main()
{
Node head;//头结点
Node *p = NULL; //记录第K个节点
Node *q = NULL; //寻找中间节点
Node *w = NULL; //逆置时返回的头节点
int ret = 0; //判断是否回文
InitList(&head);//初始化**
InsertHead(&head, 12); //头插
InsertHead(&head, 22);
InsertHead(&head, 32);
InsertHead(&head, 22);
InsertHead(&head, 12);
ret=Return(&head);
if (ret == 1)
{
printf("该单链表是回文\n");
}
else
{
printf("该单链表不是回文\n");
}
reverseHead(&head); //头插逆置法
w=reverse(&head); //头尾指向改变逆置法
q=FindMidleNode(&head);
Show(&head);// //头插法打印单链表
Show1(w); //头尾指向改变逆置法
printf("\n");
printf("%d\n", q->data);
p = LastKNode(&head, 3);
printf("%d\n", p->data);
system("pause");
return 0;
}