您的位置:首页 > 理论基础 > 数据结构算法

数据结构单链表的查找

2016-11-04 20:31 218 查看
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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  单链表