/*
思路:
快慢指针。
快指针每次走两步,慢指针每次走一步。快指针走到头时,慢指针所指的即为中间节点。
如果节点 的个数N为偶数,则中间的节点为第N/2个节点
*/
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
struct node //建立一个全局变量的结构体
{
char val; //定义一个char型的变量
struct node *next; //定义一个结构体指针
};
typedef struct node NODE; //将结构体类型重新创建一个名称
typedef NODE *LINK; //将结构体类型指针重新创建一个名称
void test(void); //建立一个测试文件
LINK create(string & str_link); //创建一个链表
void out_link(LINK pHead); //遍历整个链表
LINK find_mid_node(LINK pHead); //寻找中间节点
/*创建一个链表*/
LINK create(string & str_link)
{
int len = str_link.length(); //计算出这个字符串的长度
LINK pHead = new node(); //用new运算符在堆上分配一个结构体大小的空间
pHead->next = NULL; //头节点这里的指针暂时指向NULL
LINK pNode = pHead;
for (int i = 0; i < len; i++) //循环变量i进行10次,将字符串中的字符依次放入结构体中
{
LINK newnode = new node(); //分配一个新的节点
newnode->val = str_link[i]; //插入字符
newnode->next = NULL; //新建立节点里面的结构体指针指向NULL
pNode->next = newnode; //将新建立的节点放入链表最后一个节点的后面
pNode = newnode; //pNode 重新指向插入后链表的最后一个节点
}
return pHead; //返回指向头节点的指针
}
/*遍历整个链表,输出节点里面的字符*/
void out_link(LINK pHead)
{
if (!pHead) //入口参数检查,如果传进来的指针为NULL,则返回
return;
LINK pNode = pHead->next; //新建立的指针指向头节点下一个
while (pNode) //遍历整个链表,直到遍历到尾,跳出循环
{
cout << pNode->val; //输出该节点的值
pNode = pNode->next; //指向下一个节点
}
cout << endl; //换行
}
/*寻找中间节点,如果节点的数目为偶数,则中间节点为N/2,奇数则是(N+1)/2 */
LINK find_mid_node(LINK pHead)
{
if (!pHead) //入口参数检查
return NULL;
LINK pFast = pHead; //建立一个快指针指向头节点
LINK pSlow = pHead; //建立一个慢指针指向头节点
int count = 0; //建立一个整型变量计数
while (pFast )
{
pFast = pFast->next; //移位指向下一个节点
if ((count++) % 2 == 0)
pSlow = pSlow->next;
}
return pSlow;
}
void test(void) //建立一个测试文件
{
string str;
cout<< "请输入一串字符:" << endl;
cin >> str;
LINK pHead = create(str); //创建链表
out_link(pHead); //遍历链表
LINK pMid = find_mid_node(pHead); //寻找中间节点
if(!pMid )
cout << "寻找中间链表失败!\n";
else if (pMid == pHead)
cout << "该链表只有一个字符:" << pMid->next->val<<endl;
else
cout << "中间节点为" << pMid->val<<endl;
}
int main(int argc, char** argv)
{
test();
return 0;
}