c/c++数据结构单链表的查找(按位查找、按值查找)和建立(头插法、尾插法)总结

205 阅读2分钟

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

按位查找(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;
}

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

888

头插法

还是刚才说的,我们想一想前面的后插操作 *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;
}

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