【3】链表 (单向)

链表 (单向)
单向链表、单向循环链表、双向链表、双向循环链表
开辟的是单个的存储空间,通过地址将他们联系在一起。

 逻辑结构:线性结构
 存储结构:链式存储

单向:
1.有头单向链表
链表中的头节点数据域无效,指针域有效。
2.无头单向链表
所有节点的数据域和指针域都是有效的。

Link List.c

/**
** Created by 24122 on 2022/4/23.
**/


#include <stdio.h>
#include <stdlib.h>
#include "LinkList.h"


/**
* 1.创建一个空的有头的单链表
*/
link_t *CreateLinkList(void)
{
    //1.开辟一个头节点,data无效,next有效
    link_t *p = (link_t *) malloc(sizeof (link_t));
    //2.判断结点是否开辟成功
    if(p == NULL)
    {
        printf("CreateLinkList error!\n");
        return NULL;
    }
    //3.next有效
    p->next =NULL;
    return p;
}

/**
* 2.链表指定位置插入元素
*/
int LinkListPostInsert(link_t *p,int post,datatype data)
{
    link_t *pnew =NULL;
    //1.容错判断
    if(post < 0 || post > LinkListLength(p))
    {
        printf("LinkListPostInsert error\n");
        return -1;
    }
    //2.开辟一个结点空间保存要插入的数据
    pnew =(link_t *) malloc(sizeof (link_t));
    if(pnew ==NULL)
    {
        printf("malloc pnew error!\n");
        return -1;
    }
    //3.初始化结点内容
    pnew->data=data;
    pnew->next =NULL;
    //4.将头指针移动到要插入的前一个位置
    for (int i = 0; i < post; i++) {
        p=p->next;
    }
    //5,插入新元素:先连后面,在连前面
    pnew->next=p->next;
    p->next = pnew;
    return 0;
}

/**
 * 3.删除指定位置的元素
 */
int LinkListDeletePost(link_t *p,int post)
{
    link_t *pdel = NULL;
    //1.容错判断
    if(post <0 ||post > LinkListLength(p) -1|| LinkListIsEmpty(p))
    {
        printf("LinkListDeletePost error!\n");
        return -1;
    }
    //2.把头指针移动到要删除的前一个位置
    for (int i = 0; i < post; i++) {
        p=p->next;
    }
    //3.定义一个指针保存要删除的元素结点的地址

    pdel =p->next;
    //4.删除操作
    p->next = pdel->next;
    free(pdel);
    pdel=NULL;
    return 0;
}

/**
*4.判断链表否为空
*/
int LinkListIsEmpty(link_t *p)
{
    return p->next == NULL; //1:空  2:非空
}

/**
 * 5.遍历有头单向链表
 */
void ShowLinkList(link_t *p)
{
    while (p->next !=NULL)
    {
        p = p->next;
        printf("%d ", p->data);
    }
    putchar(10);
}

/**
* 6.计算链表长度
*/
int LinkListLength(link_t *p)
{
    int length=0;
    while(p->next !=NULL)
    {
        length++;
        p=p->next;
    }
    return length;
}

/**
* 7.查询链表的指定位置的数据
*/
datatype LinkListSearchPost(link_t *p ,int post)
{
    //1.容错判断
    if(post <0 ||post > LinkListLength(p)-1 || LinkListIsEmpty(p))
    {
        printf("LinkListSearchPost error!\n");
        return -1;
    }
    //2.移动头指针到post位置
    for (int i = 0; i <= post; i++) {
        p=p->next;
    }
    return p->data;
}

/**
* 8.查询指定数据在链表的位置
*/
int LinkListSearchData(link_t *p,datatype data)
{
    int post=0;
    while(p->next!=NULL)
    {
        p=p->next;
        if(p->data==data)
            return post;
        post++;
    }
    return -1;
}

/**
* 9.修改链表中指定的数据
*/
int LinkListChangeData(link_t *p,datatype olddata,datatype newdata)
{
    if(LinkListIsEmpty(p))
    {
        printf("9.LinkListChangeData Empty!\n");
        return -1;
    }
    while (p->next != NULL)
    {
        p=p->next;
        if(p->data ==olddata)
        {
            p->data=newdata;
        }
    }
    return 0;
}

/**
* 10.修改链表中指定位置的数据
*/
int LinkListChangePost(link_t *p,int post,datatype data)
{
    //1。容错判断
    if(post <0 ||post> LinkListLength(p)-1|| LinkListIsEmpty(p))
    {
        printf("LinkListChangePost error\n");
        return -1;
    }
    //2.移动到post位置
    for (int i = 0; i <= post; i++) {
        p=p->next;
    }
    p->data=data;
    return 0;
}

/**
* 11.删除链表中指定的数据
*/
int LinkListDeleteData(link_t *p,datatype data)
{
    link_t *pdel =NULL;
    if(LinkListIsEmpty(p))
    {
        printf("LinkListDeleteData error!\n");
        return -1;
    }
    while(p->next!=NULL)
    {
        if(p->next->data == data)
        {
            pdel=p->next;
            p->next = pdel->next;
            free(pdel);
            pdel=NULL;
        } else{
            p=p->next;
        }
    }
    return 0;
}

/**
* 12.链表的转置  1 2 3 4 5   5 4 3 2 1
*/
int LinkListInvert(link_t *p)
{
    link_t *pt = NULL;//保存头节点地址
    //断成两个链表
    link_t *pa = p->next;//保存无头的链表
    p->next=NULL;//让p断开,p保存有头空链表头节点地址
    //2.遍历无头单向链表砍头插入到有头空链表头节点之前
    while (pa != NULL)
    {
        //断开头节点
        pt=pa;
        pa = pa->next;
        pt->next=NULL;
        //将pt插入到p链表0的位置
        pt->next=p->next;
        p->next=pt;
    }
    return 0;
}

/**
* //13.清空链表
*/
void LinkListClear(link_t *p)
{
    while (!LinkListIsEmpty(p))
    {
        LinkListDeletePost(p,0);
    }
}

/**
* 14.销毁链表
*/
int LinkListDestroy(link_t *p)
{
    link_t *q =NULL;
    link_t *r =NULL;
    if(p==NULL){
        return -1;
    }
    q=p->next;
    while(q !=NULL)
    {
        r=q->next;
        free(q);
        q=r;
    }
    p->next=NULL;
    return 0;
}

LinkList.h

/**
** Created by 24122 on 2022/4/23.
**/

#ifndef DATASTRUCTURE_LINKLIST_H
#define DATASTRUCTURE_LINKLIST_H
typedef int datatype;
typedef struct node_t
{
    datatype data;
    struct node_t *next;
}link_t,*link_p;

/**
* 1.创建一个空的有头的单链表
*/
link_t *CreateLinkList(void);

/**
* 2.链表指定位置插入元素
*/
int LinkListPostInsert(link_t *p,int post,datatype data);

/**
 * 3.删除指定位置的元素
 */
int LinkListDeletePost(link_t *p,int post);

/**
*4.判断链表否为空
*/
int LinkListIsEmpty(link_t *p);

/**
 * 5.遍历有头单向链表
 */
void ShowLinkList(link_t *p);

/**
* 6.计算链表长度
*/
int LinkListLength(link_t *p);

/**
* 7.查询链表的指定位置的数据
*/
datatype LinkListSearchPost(link_t *p ,int post);

/**
* 8.查询指定数据在链表的位置
*/
int LinkListSearchData(link_t *p,datatype data);

/**
* 9.修改链表中指定的数据
*/
int LinkListChangeData(link_t *p,datatype olddata,datatype newdata);

/**
* 10.修改链表中指定位置的数据
*/
int LinkListChangePost(link_t *p,int post,datatype data);

/**
* 11.删除链表中指定的数据
*/
int LinkListDeleteData(link_t *p,datatype data);

/**
* 12.链表的转置  1 2 3 4 5   5 4 3 2 1
*/
int LinkListInvert(link_t *p);

/**
* //13.清空链表
*/
void LinkListClear(link_t *p);

/**
* 14.销毁链表
*/
int LinkListDestroy(link_t *p);



#endif //DATASTRUCTURE_LINKLIST_H

main.c

/**
** Created by 24122 on 2022/4/23.
**/
#include <stdlib.h>
#include <stdio.h>
#include "LinkList.h"

int main(){
  /*  link_t *p = CreateLinkList();
    //插入
    LinkListPostInsert(p,0,1);
    LinkListPostInsert(p,1,2);
    LinkListPostInsert(p,2,3);
    LinkListPostInsert(p,3,4);
    LinkListPostInsert(p,4,5);

    //遍历
    ShowLinkList(p);

    //删除
    LinkListDeletePost(p,2);
    LinkListDeleteData(p,4);

    //遍历
    ShowLinkList(p);

    LinkListPostInsert(p,2,3);
    LinkListPostInsert(p,3,4);

    //遍历
    ShowLinkList(p);

    //查询
    int i=LinkListSearchPost(p,2);
    printf("%d\n",i);
    int j =LinkListSearchData(p,2);
    printf("%d\n",j);

    //修改
    LinkListChangeData(p,3,30);
    LinkListChangePost(p,1,20);

    //遍历
    ShowLinkList(p);

    LinkListInvert(p);

    //遍历
    ShowLinkList(p);

    LinkListClear(p);
    //遍历
    ShowLinkList(p);

    //销毁
    LinkListDestroy(p);
    return 0;
    */
    //两个链表按顺序拼接
    link_t *p = CreateLinkList();
    link_t *q = CreateLinkList();
    link_t *r = CreateLinkList();

    LinkListPostInsert(p,0,1);
    LinkListPostInsert(p,1,3);
    LinkListPostInsert(p,2,5);
    LinkListPostInsert(p,3,7);
    LinkListPostInsert(p,4,9);
    LinkListPostInsert(p,5,10);

    LinkListPostInsert(q,0,2);
    LinkListPostInsert(q,1,4);
    LinkListPostInsert(q,2,5);
    LinkListPostInsert(q,3,8);
    LinkListPostInsert(q,4,11);
    LinkListPostInsert(q,5,15);

    ShowLinkList(p);
    ShowLinkList(q);

    int count=0;

    p=p->next;
    q=q->next;
    while (p!=NULL&&q!=NULL)
    {
        if(p->data < q->data)
        {
            LinkListPostInsert(r,count,p->data);
            p=p->next;
        } else
        {
            LinkListPostInsert(r,count,q->data);
            q=q->next;
        }
        count++;
    }
    while(p!=NULL)
    {
        LinkListPostInsert(r,count++,p->data);
        p=p->next;
    }
    while (q!=NULL){
        LinkListPostInsert(r,count++,q->data);
        q=q->next;
    }
    ShowLinkList(r);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值