数据结构单链表的查找

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&&jnext为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
#include
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 && jnext为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;
}

如有疑问,请您留言。

你可能感兴趣的:(C/C++,c++)