精华内容
下载资源
问答
  • 数据结构第一次上机 单链表 前插 后插多个元素 查找 删除(考虑多个元素) 数据结构第一次上机 单链表 前插 后插多个元素 查找 删除(考虑多个元素) 数据结构第一次上机 单链表 前插 后插多个元素 查找 删除(考虑...
  • 数据结构-单链表查找按序号查找

    千次阅读 2017-09-13 15:55:09
    cout数据查询:"; while(1) { int num; cout输入查找序号:"; cin>>num; int find_data=FindData(p,num); if(find_data!=ERROR) { cout查找结果为:"; } else { cout无法...
    #include<iostream>
    #include<stdlib.h>
    #define ERROR -40000
    using namespace std;
    
    typedef struct LNODE
    {
    	int data;
    	struct LNODE *next;
    }Lnode;
    
    Lnode *Input(int n)
    {
    	Lnode *head,*p,*q;
    	head=p=(Lnode*)malloc(sizeof(Lnode));
    	p->next=NULL;
    	for(int i=0;i<n;i++)
    	{
    		int data;
    		cin>>data;
    		q=(Lnode*)malloc(sizeof(Lnode));
    		q->data=data;
    		q->next=p->next;
    		p->next=q;
    		p=q;
    	}
    	return head;
    }
    
    int FindData(Lnode *L,int id)
    {
    	Lnode *p;
    	p=L->next;
    	int j=1;
    	while(p!=NULL&&j<id)
    	{
    		p=p->next;
    		j++;
    	}
    	if(j!=id||p==NULL) return ERROR;//书上没有此处判断n+1位置输入后bug,指针没有分配内存 
    	else return p->data;
    }
    
    int main()
    {
    	int n;
    	while(cin>>n)
    	{
    		Lnode *p=Input(n);
    		cout<<"数据查询:"<<endl;
    		while(1)
    		{
    			int num;
    			cout<<"输入查找序号:"<<endl;
    			cin>>num;
    			int find_data=FindData(p,num);
    			if(find_data!=ERROR)
    			{
    				cout<<"查找结果为:"<<find_data<<endl;
    			} 
    			else
    			{
    				cout<<"无法查询结果"<<endl; 
    			}
    		}
    	}
    	return 0;
    }

    展开全文
  • 带环单链表查找环的入口算法,结论倒是很简单,但问题是怎么推出来的。网络上很证明过程乱七八糟,这里我认认真真一步一步地给大家推证了一下,还望有所帮助。

    带环单链表的故事

    @不了解前尘往事的Reader,烦请阅读——《判断单链表是否有环的算法》

    如何找带环单链表的环的入口

    这里只说比较可行的算法吧。

    思路一:HashSet第一个重复元素就是环的入口

    按照查找单链表带环的思路二,我们用一个HashSet维护已经跑过的元素,当重复的时候,那个结点就是环的入口。这法子还算好使,不过还是老问题——空间复杂度大。

    思路二:再开一个指针与当前指针相会

    我们当前双指针停在交汇处,这里有一个位置。

    思来想去我还是给大家画个图吧:
    在这里插入图片描述

    有两个画错的地方:就是其实l1应该由node4画到node7,再就是node6上的线应该把焦点改到node7。

    大家也读过上面的文章应该也知道我的测试数据是:
    node1 → node2 → node3 → node4 → node5 → node6 → node7 → node8 → node9 → node4

    展开全文
  • 数据结构单链表查找

    千次阅读 2016-11-04 20:31:40
    1.单链表查找运算  (1)按序号查找 ① 链表不是随机存取结构  在链表中,即使知道被访问结点的序号i,也不能像顺序表中那样直接按序号i访问结点,而只能从链表的头指针出发,顺链域next逐个结点往下搜索,...

    1.单链表的查找运算 
    (1)按序号查找
    ① 链表不是随机存取结构
         在链表中,即使知道被访问结点的序号i,也不能像顺序表中那样直接按序号i访问结点,而只能从链表的头指针出发,顺链域next逐个结点往下搜索,直至搜索到第i个结点为止。因此,链表不是随机存取结构。

    ② 查找的思想方法
         计数器j置为0后,扫描指针p指针从链表的头结点开始顺着链扫描。当p扫描下一个结点时,计数器j相应地加1。当j=i时,指针p所指的结点就是要找的第i个结点。而当p指针指为null且j≠i时,则表示找不到第i个结点。
    注意:
         头结点可看做是第0个结点。

    ③具体算法实现
     
        ListNode* GetNode(LinkList head,int i)
         {//在带头结点的单链表head中查找第i个结点,若找到(0≤i≤n),
          //则返回该结点的存储位置,否则返回NULL。
          int j;
          ListNode *p;
          p=head;j=0;//从头结点开始扫描
          while(p->next&&j<i){//顺指针向后扫描,直到p->next为NULL或i=j为止
              p=p->next;
              j++;
            }
          if(i==j)
             return p;//找到了第i个结点
          else return NULL;//当i<0或i>0时,找不到第i个结点
         } 

    ④算法分析

         算法中,while语句的终止条件是搜索到表尾或者满足j≥i,其频度最多为i,它和被寻找的位置有关。在等概率假设下,平均时间复杂度为:

    (2) 按值查找
    ①思想方法 
        
     从开始结点出发,顺着链逐个将结点的值和给定值key作比较,若有结点的值与key相等,则返回首次找到的其值为key的结点的存储位置;否则返回NULL。

    ②具体算法实现

        ListNode* LocateNode (LinkList head,DataType key)
          {//在带头结点的单链表head中查找其值为key的结点
            ListNode *p=head->next;//从开始结点比较。表非空,p初始值指向开始结点
            while(p&&p->data!=key)//直到p为NULL或p->data为key为止
                 p=p->next;//扫描下一结点
             return p;//若p=NULL,则查找失败,否则p指向值为key的结点
           }

    ③算法分析

         该算法的执行时间亦与输入实例中key的取值相关,其平均时间复杂度分析类似于按序号查找,为O(n)。

     

    附源代码

    #include<stdio.h>
    #include<stdlib.h>
    typedef struct node
    {
    char data;
    struct node *next;
    }ListNode;
    typedef ListNode * LinkList;

    //头插入法
    LinkList creatListF(void)
    {
    LinkList head=NULL;
    ListNode *s;
    char ch;
    ch=getchar();

    while(ch!='\n')
    {
    s=(ListNode *)malloc(sizeof(ListNode));
    if(s==NULL)
    {
    return NULL;
    }
    s->data=ch;
    s->next=head;
    head=s;//head要不断向前移动,一直指着最前线,这样存储的数据与输入的数据顺序相反
    ch=getchar();
    }

    return head;
    }

    //尾插入法
    LinkList creatListR(void)
    {
    LinkList head=NULL,r=NULL;
    ListNode *s;
    char ch;
    ch=getchar();

    while(ch!='\n')
    {
    s=(ListNode *)malloc(sizeof(ListNode));

    s->data=ch;
    if(head==NULL)
    head=s;//新结点插入空表
    else
    r->next=s;//如果是头结点,不执行这一步,头结点特别处理

    r=s;//一直指向最后一个,无论点,r肯定是指向最后一个
    if(r!=NULL)
    r->next=NULL;//对于非空表,将尾结点指针域置空,防止内存读写错误

    ch=getchar();
    }

    return head;
    }

    //根据查找第i个结点
    ListNode * getNodebyi(LinkList head,int i)
    {
    LinkList p=head;
    int j=0;
    while(p->next && j<i)//如果p->next为NULL,那么没有后结点,关键判断后继结点
    {
    p=p->next;
    j++;
    }
    //循环结束后,要不p为NULL,要不j=i
    if(j==i)
    {
    return p;
    }
    else
    return NULL;
    }
    ListNode * getNodebykey(LinkList head,char key)
    {
    LinkList p=head;//本程序是不带头结点的
    while(p && key!=p->data)//直到p为NULL或p->data为key为止
    {
    p=p->next;
    }
    return p;//若p=NULL,则查找失败,否则p指向值为key的结点

    }

    void print(LinkList head)
    {

    while(head)
    {
    printf("%c ",head->data);
    head=head->next;//在创建时,要将head设置为NULL,否则内存出错;LinkList head这样声明只是指向一个未知的值

    }
    }
    int main()
    {
    //LinkList head=creatListF();
    LinkList head=creatListR();
    print(head);
    //LinkList node=getNode(head,2);
    //printf("\n查找第2个\n");
    LinkList node=getNodebykey(head,'c');
    printf("\n查找第2个\n");
    printf("%c",node->data);
    getchar();
    return 0;
    }

    展开全文
  • 单链表查找倒数第k节点

    千次阅读 2014-03-18 23:24:24
    题目:输入一单向链表,输出该链表中倒数第k结点。链表的倒数第0结点为链表的尾指针。 分析:为了得到倒数第k结点,很自然的想法是先走到链表的尾端,再从尾端回溯k步。可是输入的是单向链表,只有从前往后...

    题目:输入一个单向链表,输出该链表中倒数第k个结点。链表的倒数第0个结点为链表的尾指针。链表结点定义如下:

    struct ListNode
    {
          int       m_nKey;
          ListNode* m_pNext;
    };

    分析:为了得到倒数第k个结点,很自然的想法是先走到链表的尾端,再从尾端回溯k步。可是输入的是单向链表,只有从前往后的指针而没有从后往前的指针。因此我们需要打开我们的思路。

    既然不能从尾结点开始遍历这个链表,我们还是把思路回到头结点上来。假设整个链表有n个结点,那么倒数第k个结点是从头结点开始的第n-k-1个结点(从0开始计数)。如果我们能够得到链表中结点的个数n,那我们只要从头结点开始往后走n-k-1步就可以了。如何得到结点数n?这个不难,只需要从头开始遍历链表,每经过一个结点,计数器加一就行了。

    这种思路的时间复杂度是O(n),但需要遍历链表两次。第一次得到链表中结点个数n,第二次得到从头结点开始的第n-k-1个结点即倒数第k个结点。

    如果链表的结点数不多,这是一种很好的方法。但如果输入的链表的结点个数 很多,有可能不能一次性把整个链表都从硬盘读入物理内存,那么遍历两遍意味着一个结点需要两次从硬盘读入到物理内存。我们知道把数据从硬盘读入到内存是非 常耗时间的操作。我们能不能把链表遍历的次数减少到1?如果可以,将能有效地提高代码执行的时间效率。

    如果我们在遍历时维持两个指针,第一个指针从链表的头指针开始遍历,在第k-1步之前,第二个指针保持不动;在第k-1步开始,第二个指针也开始从链表的头指针开始遍历。由于两个指针的距离保持在k-1,当第一个(走在前面的)指针到达链表的尾结点时,第二个指针(走在后面的)指针正好是倒数第k个结点。

    这种思路只需要遍历链表一次。对于很长的链表,只需要把每个结点从硬盘导入到内存一次。因此这一方法的时间效率前面的方法要高。

    思路一的参考代码:

    ///
    // Find the kth node from the tail of a list
    // Input: pListHead - the head of list
    //        k         - the distance to the tail
    // Output: the kth node from the tail of a list
    ///
    ListNode* FindKthToTail_Solution1(ListNode* pListHead, unsigned int k)
    {
          if(pListHead == NULL)
                return NULL;

          // count the nodes number in the list
          ListNode *pCur = pListHead;
          unsigned int nNum = 0;
          while(pCur->m_pNext != NULL)
          {
                pCur = pCur->m_pNext;
                nNum ;
          }

          // if the number of nodes in the list is less than k
          // do nothing
          if(nNum < k)
                return NULL;

          // the kth node from the tail of a list 
          // is the (n - k)th node from the head
          pCur = pListHead;
          for(unsigned int i = 0; i < nNum - k; i)
                pCur = pCur->m_pNext;

           return pCur;
    }

    思路二的参考代码:

    ///
    // Find the kth node from the tail of a list
    // Input: pListHead - the head of list
    //        k         - the distance to the tail
    // Output: the kth node from the tail of a list
    ///
    ListNode* FindKthToTail_Solution2(ListNode* pListHead, unsigned int k)
    {
          if(pListHead == NULL)
                return NULL;

          ListNode *pAhead = pListHead;
          ListNode *pBehind = NULL;

          for(unsigned int i = 0; i < k; i)
          {
                if(pAhead->m_pNext != NULL)
                      pAhead = pAhead->m_pNext;
                else
                {
                      // if the number of nodes in the list is less than k, 
                      // do nothing
                      return NULL;
                }
          }

          pBehind = pListHead;

          // the distance between pAhead and pBehind is k
          // when pAhead arrives at the tail, p
          // Behind is at the kth node from the tail
          while(pAhead->m_pNext != NULL)
          {
                pAhead = pAhead->m_pNext;
                pBehind = pBehind->m_pNext;
          }

          return pBehind;
    }

    讨论:这道题的代码有大量的指针操作。在软件开发中,错误的指针操作是大部分问题的根源。因此每个公司都希望程序员在操作指针时有良好的习惯,比如使用指针之前判断是不是空指针。这些都是编程的细节,但如果这些细节把握得不好,很有可能就会和心仪的公司失之交臂。

    另外,这两种思路对应的代码都含有循环。含有循环的代码经常出的问题是在循环结束条件的判断。是该用小于还是小于等于?是该用k还是该用k-1?由于题目要求的是从0开始计数,而我们的习惯思维是从1开始计数,因此首先要想好这些边界条件再开始编写代码,再者要在编写完代码之后再用边界值、边界值减1、边界值加1都运行一次(在纸上写代码就只能在心里运行了)。

    扩展:和这道题类似的题目还有:输入一个单向链表。如果该链表的结点数为奇数,输出中间的结点;如果链表结点数为偶数,输出中间两个结点前面的一个。如果各位感兴趣,请自己分析并编写代码。


    展开全文
  • 数据结构-静态单链表节点的...在实现单链表的时候,有时可以使用一维数组来表示,静态单链表节点的查找操作是静态单链表数据结构对象操作的重要内容,请您写一程序完成在一静态单链表查找某一节点的操作。 请
  • 接上一篇,我们继续聊聊单链表! 这一篇
  • C语言创建一个单链表实现键盘输入数据以及增删查

    千次阅读 多人点赞 2020-10-18 17:14:56
    作为一编程小白,在这里发表自己的第一篇博客,心里还是有点紧张。...我们都知道,链表是由一又一节点构成,每节点又分为数据域和指针域(eg:p->data/p->next)。 ![在这里插入图片描述](https://img.
  • 逆置一个单链表和从尾到头打印不一样,打印不改变节点的位置,只是将数据反着打印一遍,而逆置就是要改变节点的位置。 可以先创建一空节点,然后从第一开始每次在单链表上拿一节点,前插给创建的节点,单链表...
  • 1.【基础题】–逆置/反转单链表+查找单链表的倒数第k节点,要求只能遍历一次链表 2.【附加题】–实现一Add函数,让两数相加,但是不能使用+、-、*、/等四则运算符。ps:也不能用++、–等等**1,基础题:**/* 注...
  • 数据结构 单链表

    千次阅读 2014-10-26 23:16:33
    学了这么长的时间的数据结构了,下面是我自己整理的数据结构中的单链表数据。拿来和大家分享一下,也请大家给我提提程序中的不足之处。单链表中用到了很的指针。在指针的直来直去中,很的初学者都被搞得晕头转向...
  • 查找单链表中倒数第k结点

    千次阅读 2013-12-19 11:18:15
    本文转自:程序员面试题6--查找链表中倒数第k结点 题目:输入一单向链表,输出该链表中倒数第k结点。链表的倒数第0结点为链表的尾指针。链表结点定义如下: struct ListNode {  int m_nKey;  ...
  • 用C或者C++ 设计一个算法,查找带头节点的非空单链表L中第一个最大节点(最大节点可能有多个),并返回该节点的逻辑序号。
  • 数据结构之单链表

    千次阅读 多人点赞 2021-08-01 23:17:40
    单链表的增删改查4.1 单链表之尾插4.1.1 单链表之开辟空间4.1.2 单链表之打印值4.2单链表之头插4.3单链表之尾删4.4 单链表之头删4.5单链表之查链表长度4.6单链表之判断链表是否为空4.7单链表查找某一值4.8单链表...
  • 双向链表每一节点包含三部分,在单链表的基础上了一指向前置节点的prev指针 链表的第一节点被称为头节点,最后一节点被称为尾节点,尾结点的next指针指向null 链表在内存中的存储方式为随机存储 时间...
  • 1. 求单链表有效节点的个数 // 1. 求单链表有效节点的个数 public int accountLink() { // 获取指针 HeroLink temp = head; // 统计有效节点的个数 int count = 0; ... // 遍历到最后一节点
  • 单链表

    2015-11-03 16:58:21
    单链表
  • 数据结构系列】单链表

    千次阅读 多人点赞 2019-11-05 22:03:45
    最近也一直在思考该写点什么文章,想了很久,还是决定重新编写一下数据结构的相关内容,关于数据结构的重要性就不用我说了,之前的文章中我也写过,但实现语言是Java。其实对于数据结构的学习,最好还是用C语言来...
  • 单向非循环链表查询倒数第N个数据 思路1: 先从头到尾遍历一遍链表记录元素总数,用总数–要查询位数,重新循环遍历表即可(效率不高就不写代码了) 思路2: 利用快慢指针,定义两个指针(fast&slow),因为查询的...
  • 数据结构:单链表实现

    千次阅读 2021-01-28 17:51:01
    单链表的python实现 目录*顺序表(这不是本次重点,简单介绍一下)*链式表   首先说下线性表,线性表是一种最基本,最简单的数据结构,通俗点讲就是一维的存储数据的结构。  线性表分为顺序表和链接表: ...
  • 数据结构——单链表

    2017-06-08 23:38:53
    但是顺序表有很的不足,比如要给顺序表的前面插入一个数据,就必须先把后面的数据先一个一个的往后挪动,然后再将所要插入的数据放进去。就相当于一个数组一样。 还有就是顺序表的大小分配,如果采用静态分配...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 27,751
精华内容 11,100
关键字:

单链表查找多个数据