c语言单链表的创建链表问题

1、实现单链表逆置
&  无头结点:
1 #include&stdio.h&
2 #include&stdlib.h&
4 typedef struct node{
struct node *
9 //创建链表
10 Node *CreateList(void){
int val,i,n;
Node *head,*p,*q;
head=NULL;
printf("请输入您要建立的链表长度:\n");
scanf("%d",&n);
printf("请输入您要输入的数据:\n");
for(i=0;i&n;i++){
scanf("%d",&val);
p=(Node*)malloc(sizeof(Node));
if(head==NULL)
q-&next=p;
p-&next=NULL;
32 //链表的逆置
33 Node *ReverseList(Node *head){
Node *p,*q,*r;
p-&next=r;
46 //输出链表
47 void ShowList(Node *head){
printf("%d ",p-&data);
printf("\n");
57 void main(){
head=CreateList();
printf("链表逆置前的数据:\n");
ShowList(head);
head=ReverseList(head);
printf("链表逆置后的数据:\n");
ShowList(head);
  运行演示:
2、判断单链表是否有环
  判断链表是否存在环的办法为:
  设置两个指针(fast,slow),初始值都指向头指针,slow每次前进一步,fast每次前进两步,如果链表存在环,则fast必定先进入环,而slow后进入环,两个指针必定相遇。(当然,fast先行从头到尾部为NULL,则为无环链表)程序如下:
1 #include&stdio.h&
2 #include&stdlib.h&
4 typedef struct node{
struct node *
7 }Node, *NodeL
9 bool IsExitsLoop(NodeList head){
NodeList slow=head,fast=
while(fast && fast-&next){
slow=slow-&
fast=fast-&next-&
if(slow==fast)
return !(fast==NULL || fast-&next==NULL);
20 void main(){
//创建一个有环的单链表
NodeList head=NULL,p,q;
for(int i=1;i&=5;i++){
p=(NodeList)malloc(sizeof(Node));
p-&elem=i;
if(head==NULL)
q-&next=p;
p=(NodeList)malloc(sizeof(Node));
p-&elem=6;
q-&next=p;
q-&next=head-&next-&next-&
//判断单链表是否存在环
printf("单链表是否存在环: ");
bool b=IsExitsLoop(head);
printf("%s\n",b==false?"false":"true");
  运行结果显示:
3、如果单链表有环,则找到环的入口点
  当fast若与slow相遇时,slow肯定没有遍历完链表,而fast已经在环内循环了n圈(1&=n),假设slow走了s步,而fast走了2s步(fast步数还等于s加上在环上多转的n圈),设环长为r,则:
    2s = s + n*r;  
    s = n*r;
设整个链表长为L,入口环与相遇点距离为x,起点到环入口点的距离为a。
    a + x = n*r;    
    a + x = (n-1)*r + r = (n-1)*r + L -a;    
    a = (n-1)r + (L & a & x);
(L & a & x)为相遇点到环入口点的距离,由此可知,从链表头到环入口点等于(n-1)循环内环+相遇点到环入口点,于是我们从链表头、与相遇点分别设一个指针,每次各走一步,两个指针必定相遇,且相遇第一点为环入口点。程序描述如下:
1 #include&stdio.h&
2 #include&stdlib.h&
4 typedef struct node{
struct node *
7 }Node, *NodeL
9 //寻找环的入口点
10 NodeList FindLoopPort(NodeList head){
NodeList slow=head,fast=
while(fast && fast-&next){
slow=slow-&
fast=fast-&next-&
if(slow==fast)
if(fast==NULL||fast-&next==NULL)
return NULL;
while(slow!=fast){
slow=slow-&
fast=fast-&
28 void main(){
//创建一个有环的单链表
NodeList head=NULL,p,q;
for(int i=1;i&=5;i++){
p=(NodeList)malloc(sizeof(Node));
p-&elem=i;
if(head==NULL)
q-&next=p;
p=(NodeList)malloc(sizeof(Node));
p-&elem=6;
q-&next=p;
q-&next=head-&next-&next-&
//寻找环的入口点
NodeList list=FindLoopPort(head);
printf("环的入口节点元素值为:%d\n",list-&elem);
  运行结果显示:
4、判断两个单链表是否相交,如果相交,给出相交的第一个点(两个链表都不存在环)
  比较好的方法有两个:
  一、将其中一个链表首尾相连,检测另外一个链表是否存在环,如果存在,则两个链表相交,而检测出来的依赖环入口即为相交的第一个点。
  二、如果两个链表相交,那么两个链表从相交点到链表结束都是相同的节点,我们可以先遍历一个链表,直到尾部,再遍历另外一个链表,如果也可以走到同样的结尾点,则两个链表相交。这时我们记下两个链表length,再遍历一次,长链表节点先出发前进(lengthMax-lengthMin)步,之后两个链表同时前进,每次一步,相遇的第一点即为两个链表相交的第一个点。
阅读(...) 评论()var sogou_ad_id=731545;
var sogou_ad_height=90;
var sogou_ad_width=980;2008年11月 扩充话题大版内专家分月排行榜第二
2010年5月 C/C++大版内专家分月排行榜第三2010年3月 C/C++大版内专家分月排行榜第三2010年1月 C/C++大版内专家分月排行榜第三
2012年11月 Linux/Unix社区大版内专家分月排行榜第二2011年8月 Linux/Unix社区大版内专家分月排行榜第二2008年10月 C/C++大版内专家分月排行榜第二
2012年8月 Linux/Unix社区大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。C语言单向循环链表解决约瑟夫问题
据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。
17世纪的法国数学家加斯帕在《数目的游戏问题》中讲了这样一个故事:15个教徒和15 个非教徒在深海上遇险,必须将一半的人投入海中,其余的人才能幸免于难,于是想了一个办法:30个人围成一圆圈,从第一个人开始依次报数,每数到第九个人就将他扔入大海,如此循环进行直到仅余15个人为止。问怎样排法,才能使每次投入大海的都是非教徒。
*问题分析与算法设计
约瑟夫问题并不难,但求解的方法很多;题目的变化形式也很多。这里给出一种实现方法。
题目中30个人围成一圈,因而启发我们用一个循环的链来表示。可以使用结构数组来构成一个循环链。结构中有两个成员,其一为指向下一个人的指针,以构成环形的链;其二为该人是否被扔下海的标记,为1表示还在船上。从第一个人开始对还未扔下海的人进行计数,每数到9时,将结构中的标记改为0,表示该人已被扔下海了。这样循环计数直到有15个人被扔下海为止。
约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀掉的人的序号为5,4,6,2,3。最后剩下1号。
假定在圈子里前K个为好人,后K个为坏人,你的任务是确定这样的最少M,使得所有的坏人在第一个好人之前被杀掉。
解决方案:
/*************************************************************************
> File Name: josefu.c
> Author: Baniel Gao
> Blog: blog.csdn.net/createchance
> Created Time: Thu 19 Dec :21 PM CST
************************************************************************/
typedef struct josefu
struct josefu *
josefu_list *josefu_init(int num);
josefu_list *josefu_begin(josefu_list *list, int rule);
josefu_list *josefu_node(int num);
int josefu_free(josefu_list *list);
int main(void)
josefu_list *
puts("Please input number and rules: ");
scanf("%d%d", &num, &rule);
list = josefu_init(num);
list = josefu_begin(list, rule);
josefu_free(list);
josefu_list *josefu_init(int num)
josefu_list *
josefu_list *list = josefu_node(1);
for(i = i > 1; i--) {
new = josefu_node(i);
new->next = list->
list->next =
josefu_list *josefu_node(int num)
josefu_list *p = NULL;
p = (josefu_list *)malloc(sizeof(josefu_list));
josefu_list *josefu_begin(josefu_list *list, int rule)
josefu_list *tmp = NULL;
for(counter = 1; list->next != counter++) {
if(counter == rule - 1) {
tmp = list->
list->next = tmp->
free(tmp);
counter = 0;
josefu_show(list);
list = list->
int josefu_show(josefu_list *list)
josefu_list *p =
if(list == NULL)
printf("%5d",p->data);
} while(list != p);
putchar('\n');
int josefu_free(josefu_list *list)
free(list);
运行实例:

我要回帖

更多关于 c语言链表教程 的文章

 

随机推荐