数据结构单链表的查找

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;
}

  • 18
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值