c 语言数据结构系列,单链表的查找和建立操作

单链表的查找(带头结点)

按位查找(GetElem(L,i))

获取表L 中第i 个位置的元素的值(带头结点),可把头结点看成第0 个结点,程序代码如下:

LNode *GetElem(LinkList L,int i){
   if(i<0)
       return null;
   LNode *p; //定义指针p 指向当前扫描到的结点
   int j=0; //当前p 指向的是第几个结点
   p=L; //L指向头结点,头结点是第0个结点,是不存数据的
   while(p!=NULL&&j<i){
       p=p->next;
       j++;
  }
   return p;
}

看了上面的代码片段,我们是不是感觉很熟悉呢?是的,它于我们在前面的在第 i 个位置插入元素e (带头结点)的代码是一样的,只不过这里是找第i 个结点,而前面循环找的是第 i-1 个结点。

按值查找(LocateElem(L,e))

找到数据域==e 的结点,部分程序代码片段如下:

LNode * LocateElem(LinkList L,ElemType e){
   LNode *p=L->next;
   //从第1个结点开始查找数据域为e的结点
   while(p!=NULL&&p->data!=e)
       p=p->next;
   return p; //找到结点返回该结点
}

通过上面的启发,我们是不是觉得求一个单链表的长度就很容易了呢?看看下面的代码,你说简不简单?

int Length(LinkList L){
   int len=0; //统计表长
   LNode *p=L;
   while(p->next!=NULL){
       p=p->next;
       len++;
  }
   return len;
}

单链表的建立(带头结点)

如果给你很多个数据元素(ElemType),你会把他们存到一个单链表里吗?

  • 初始换一个单链表(前面的文章讲过单链表初始化的实现)

  • 在其头部或尾部进行插入数据元素。就我的理解,就是对指定结点进行后插操作。

尾插法

结合前面学习的后插操作,我们来实现一下尾插法建立单链表:

LinkList List_Tailnsert(LinkList &l){
   int x; //设ElemType为整型
   L=(LinkList)malloc(sizeof(LNode)); //建立头结点
   LNode *s,*r=L; //r为表尾指针
   scanf("%d",&x); //输入结点的值
   while(x!=2022){ //输入2022表示结束
       s=(LNode *)malloc(sizeof(LNode)); //申请一个结点并把s指向这个结点
       s->data=x;
       r->next=s;
       r=s; //r指向新的表尾结点,即永远保证r 指向最后一个结点
       scanf("%d",&x);
  }
   r->next=NULL; //尾结点指针置空
   return L;
}

下面结合动图理解一下上面的几行代码:

c 语言数据结构系列,单链表的查找和建立操作

头插法

还是刚才说的,我们想一想前面的后插操作 InsertNextNode(LNode *p,ElemType e) 的实现,然后我们再来看一看用头插法建立单链表的实现:

LinkList List_HeadInsert(LinkList &L){
   LNode *s;
   int x;
   L=(LinkList)malloc(sizeof(LNode)); //创建头结点
   L->next=NULL; //初始化空链表,防止指向不安全区域,注意下哦
   scanf("%d",&x);
   while(x!=2022){
       s=(LNode*)malloc(sizeof(LNode)); //创建新结点
       s->data=x;
       s->next=L->next;
       L-next=s; //将新结点插入表中,L 为头指针
       scanf("%d",&x);
  }
   return L;
}

不知道我们发现了没有,头插法建立单链表可以实现单链表的逆置!

上一篇:中级-day4作业


下一篇:单链表基本操作(尾插,头插,删除,查找,修改,打印)