单向链表是微软笔试常考的,参考这里:http://www.cnblogs.com/tdyizhen1314/archive/2012/04/03/2431124.html
#include<iostream> using namespace std; struct node{ int data; struct node* next; }; //定义一个名字呢 node* create(unsigned int n){ if(n==0){ cout<<"ensure n>0. (create failure)"<<endl; return NULL; } //assert(n>0); node* head=new node;//new一个struct cout<<"#1:"; cin>>head->data; head->next=NULL; int i; node *pre=head; node *cur=NULL; for(i=1;i<n;i++){ cur=new node; cout<<"#"<<i+1<<":"; cin>>cur->data; cur->next=NULL; pre->next=cur; pre=cur; } return head; } /* 丑方法: node* reverse(node* list){ node* one=list; node* two=NULL; node* three=NULL; if(list->next!=NULL) two=list->next; else return list; if(list->next->next!=NULL) three=list->next->next; one->next=NULL; while(two!=NULL){ two->next=one; one=two; two=three; if(three!=NULL) three=three->next; else break; } return one; } */ /*问题1:链表反转 思路:head指针不断后移,指针反向即可 */ void reverse(node*& head){ /*1. 先讨论空链表和只有一个节点的情况*/ if(head==NULL) return; if(head->next==NULL) return; /*2. 在处理普通情况*/ node* p=head; node* q=head->next; while(q!=NULL){ node* temp=q->next; q->next=p; p=q; q=temp; } head->next=NULL; //反转前的链表头特殊处理 head=p; } /*问题2:删除不知头结点链表的某个节点 如果单向链表不知道头节点,一个指针指向其中的一个节点,问如何删除这个指针指向的节点 思路:下一个节点的值复制给该节点,然后删除下一个节点即可 */ void deleteNodeInList(node*& n){ if(n==NULL) return; if(n->next==NULL){ delete n; n=NULL; return; } /*一般情况:存在下一个节点*/ node* nextNode=n->next; n->data=nextNode->data; n->next=nextNode->next; delete nextNode; } /* 问题3:判断链表中是否有环 思路: 设置两个指针,一个步长为1,另一个步长为2,依次后移,如果相遇且都不为空,则有环。 解释: que: 跑步能追上确实很容易理解。但问题是,跑步是连续的,而这里不是。因为有一个指针是跳两步的,不是连续的,怎么证明这样也肯定能碰上;好像只能证明一定能超过啊 ans: 画上一个圈就知道啦!速度快的开始肯定会超过慢的. 一个步长1(乌龟),另外一个步长2(兔子),因此兔子一次追上1个单位,如果确实是个圈的话肯定会追上并且是相遇在同一个单位之内! */ node* hasLoop(node* head){ //返回第一次交汇的点(能写成输入参数吗) if(head==NULL) return NULL; if(head->next==NULL) return NULL; /*至少有2个节点的单链表*/ node* p=head; node* q=head; while(true){ if(p==NULL || q==NULL) return NULL; if(p->next==NULL || q->next==NULL) return NULL; if(q->next->next==NULL) return NULL; //p步长为1后移 p=p->next; //q步长为2后移 q=q->next->next; //如果p,q重合在非NULL节点,则有环 if(p==q && p!=NULL){ return p; } } } /* 问题4:找出环的入口节点 思路: 当fast若与slow相遇时,slow肯定没有走遍历完链表,而fast已经在环内循环了n圈(1<=n)。 假设slow走了s步,则fast走了2s步(fast步数还等于s 加上在环上多转的n圈),设环长为r,则: 2s = s + nr <==> s= nr 设入口环与相遇点距离为x,x<r,起点到环入口点的距离为a. a = s - x = (n-1)r+ (r-x), 而r-x即为fast再次到环入口点时的步数 由此可知,从链表头到环入口点等于(n-1)循环内环+相遇点到环入口点,于是我们从链表头、与相遇点分别设一个指针,每次各走一步,两个指针必定相遇,且相遇第一点为环入口点。 */ node* getLoopHead(node* list){ node* inter; //第一次交汇点 if( (inter=hasLoop(list)) !=NULL ){ node* p=list; while(true){ if(p==inter) return p; p=p->next; inter=inter->next; } } return NULL; } /* 问题5:找出倒数第k个节点 */ node* findLastK(node* head, unsigned int k){ /* back指向开始处, front指向前于它(k-1)个位置处 */ node* back=head; node* front=head; for(int i=1;i<k;i++){ if(front==NULL) return NULL; front=front->next; } if(front==NULL) return NULL; /* 后移 */ while(front->next){ back=back->next; front=front->next; } return back; } /* 问题6: 《编程之美》 3.6 判断两个链表是否相交 */ void traverse(node* list){ node* p=list; while(p!=NULL){ cout<<p->data<<"\t"; p=p->next; } cout<<endl; } int main(){ cout<<"****************创建****************"<<endl; node* list=create(6); traverse(list); /* cout<<"****************反转****************"<<endl; reverse(list); traverse(list); node* list2=create(2); traverse(list2); reverse(list2); traverse(list2); node* list3=create(1); traverse(list3); reverse(list3); traverse(list3); node* list4=create(0); cout<<"****************删除孤立节点****************"<<endl; deleteNodeInList(list->next->next); traverse(list); cout<<"**************** 检测环 | 找出环的入口节点 ****************"<<endl; if(hasLoop(list)==NULL) cout<<"无环"<<endl; else cout<<"有环"<<endl; //奇数(3)长度环 node* n1=new node; node* n2=new node; node* n3=new node; node* n4=new node; n1->data=1; n2->data=2; n3->data=3; n4->data=4; n1->next=n2; n2->next=n3; n3->next=n4; n4->next=n2; if(hasLoop(n1)==NULL) cout<<"无环"<<endl; else cout<<"有环"<<endl; node* inter=getLoopHead(n1); cout<<"环入口: "<<inter->data<<endl; delete n1; delete n2; delete n3; delete n4; //偶(2)长度环 n1=new node; n2=new node; n3=new node; n4=new node; n1->data=1; n2->data=2; n3->data=3; n4->data=4; n1->next=n2; n2->next=n3; n3->next=n4; n4->next=n3; if(hasLoop(n1)==NULL) cout<<"无环"<<endl; else cout<<"有环"<<endl; inter=getLoopHead(n1); cout<<"环入口: "<<inter->data<<endl; delete n1; delete n2; delete n3; delete n4; */ cout<<"****************寻找倒数第k个节点****************"<<endl; node* last0=findLastK(list,0); cout<<last0->data<<endl; node* last1=findLastK(list,1); cout<<last1->data<<endl; node* last3=findLastK(list,3); cout<<last3->data<<endl; node* last4=findLastK(list,4); cout<<last4->data<<endl; system("pause"); return 0; }
相关推荐
单向链表是一种基本的数据结构,它在计算机科学和编程中有着广泛的应用。与数组不同,链表中的元素不是在内存中连续存储的,而是通过指针或引用连接在一起,形成一个逻辑上的线性序列。单向链表的每个节点包含两部分...
单向链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。在C++编程中,为了实现通用性,我们通常会使用模板类来创建单向链表,以便它可以处理不同类型的元素。标题"单向链表类...
1.随机产生或键盘输入一组元素,建立一个带头结点的单向链表(无序)。 2.遍历单向链表。 3.把单向链表中元素逆置(不允许申请新的结点空间)。 4.在单向链表中删除所有的偶数元素结点。 5.编写在非递减...
04.单向链表以及单向链表的应用.ppt
单向链表是一种基本的数据结构,它在计算机科学中被广泛应用,特别是在算法和数据结构的实现中。在Java编程中,单向链表通常通过定义一个节点类来实现,每个节点包含数据和指向下一个节点的引用。下面我们将深入探讨...
本文将详细讲解如何在C#中实现单向链表,结合源码解析来帮助你深入理解其内部机制。 首先,我们要知道什么是单向链表。单向链表是由一系列节点组成,每个节点包含两个部分:数据域和指针域。数据域存储实际的数据,...
实验使用VC++ 6.0作为编程工具,旨在通过实践来深入理解和掌握单向链表的相关操作。 实验目的: 1. 掌握单向链表的存储结构和实现方式。单向链表的每个节点由数据域和指针域组成,指针域指向下一个节点。在内存中,...
这是一个单向链表,它具有插入与删除节点的功能。Entry类实现了链表的各节点。
Java SE程序 类实现单向链表Java SE程序 类实现单向链表Java SE程序 类实现单向链表Java SE程序 类实现单向链表Java SE程序 类实现单向链表Java SE程序 类实现单向链表Java SE程序 类实现单向链表Java SE程序 类实现...
将一个单向链表反向连接
本资源提供的是针对初学者设计的链表学习材料,包括单向链表和双向链表的实现。下面将详细讲解这两种链表的数据结构及其操作。 1. **单向链表**: 单向链表是一种线性数据结构,每个节点包含两部分:数据域和指针...
本文将深入探讨两种重要的线性数据结构——单向链表和双向链表,以及它们在实际编程中的应用。 单向链表是一种线性数据结构,它的每个元素(称为节点)包含两部分:数据域,用于存储实际的数据;指针域,用于存储下...
本主题将深入探讨由C语言实现的单向链表(slist.h)和双向链表(blist)。这两种链表各有特点,适用于不同的场景,对于理解和掌握数据结构与算法至关重要。 ### 单向链表(slist.h) 单向链表是一种线性数据结构,...
单向链表类定义及测试文件 对应于数据机构与算法分析(c++版)第三版或第二版 作者Clifford A.Shaffer 重庆大学使用教材
在IT领域,数据结构是编程基础中的重要组成部分,而单向链表作为基本的数据结构之一,在许多场景下都有着广泛的应用。本项目以Flash AS3.0为编程语言,实现了一个单向链表的数据结构,这对于理解和应用单向链表概念...
单向链表是一种基本的数据结构,它在计算机科学和编程,特别是C#中扮演着重要角色。单向链表与数组不同,不提供随机访问,但允许高效地插入和删除元素,尤其在列表的中间或末尾。接下来,我们将深入探讨C#中单向链表...
单向链表是一种基本的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。在本文中,我们将深入探讨如何实现单向链表的各种操作,包括建立链表、添加元素、删除元素、翻转链表(包括递归方法)...
数据结构,c语言实现的单向链表。代码分享 struct LinkNode { int data; struct LinkNode *next; }; typedef struct LinkNode *Lnode;
C++进阶学习——单向链表的实现,相关教程链接如下: http://blog.csdn.net/tennysonsky/article/details/49685199
java语言模拟单向链表,JAVA数据结构