C语言数据结构单带头结点的链表和头指针型单链表的基本操作

#include <stdio.h>
#include <stdlib.h>
#define newNode (LinkedList *)malloc(sizeof(LinkedList)) //快捷生成新结点

typedef struct k
{ //定义单链表
    int data;
    struct k *next;
} LinkedList;

LinkedList *append()
{ //尾插法,返回一个带头结点的单链表,注意返回的只能是地址
    int x;
    LinkedList *h, *p;                            // h是头结点的指针
    h = (LinkedList *)malloc(sizeof(LinkedList)); //创建一个结点,即头结点
    h->next = NULL;                               //创建结点后对next初始化
    //下面向单链表添加元素
    LinkedList *tail;
    printf("请输入一组数,以-1结束 \n");
    scanf("%d", &x);
    tail = h;
    while (x != -1)
    {
        //造新的结点
        p = newNode;
        //对p的各个域进行初始化赋值
        p->data = x;
        p->next = NULL;
        //将p插入到链表的尾部
        tail->next = p;
        tail = p;
        //继续读入一个x
        scanf("%d", &x);
    }
    return h;
}
LinkedList *append2()
{ //尾插法,返回一个带头指针的单链表,注意返回的只能是地址
    int x;
    LinkedList *h, *p; // h是头结点的指针
    printf("请输入一组数,以-1结束 \n");
    scanf("%d", &x);
    if (x == -1)
        return NULL;
    h = (LinkedList *)malloc(sizeof(LinkedList)); //创建一个结点,即头结点
    h->next = NULL;
    h->data = x;
    //下面向单链表添加元素
    LinkedList *tail;
    tail = h;
    scanf("%d", &x);
    while (x != -1)
    {
        //造新的结点
        p = newNode;
        //对p的各个域进行初始化赋值
        p->data = x;
        p->next = NULL;
        //将p插入到链表的尾部
        tail->next = p;
        tail = p;
        //继续读入一个x
        scanf("%d", &x);
    }
    return h;
}
LinkedList *crea_h()
{ //使用头插法输入带头结点单链表
    int x;
    LinkedList *h, *p;
    h = (LinkedList *)malloc(sizeof(LinkedList));
    h->next = NULL;
    LinkedList *head;
    printf("请输入一组数,以-1结束\n");
    scanf("%d", &x);
    head = h;
    while (x != -1)
    {
        p = newNode;
        p->data = x;
        p->next = NULL;
        p->next = head->next;
        head->next = p;
        scanf("%d", &x);
    }
    return h;
}
void show(LinkedList *h)
{ //打印带头结点的单链表h
    LinkedList *p;
    for (p = h->next; p != NULL; p = p->next)
        printf("%d ", p->data);
    printf("\n");
}
void show2(LinkedList *h)
{ //打印头指针单链表h
    LinkedList *p;
    for (p = h; p != NULL; p = p->next)
        printf("%d ", p->data);
    printf("\n");
}
void find_del(LinkedList *h, int x)
{ //在头结点单链表中查找x并删除
    LinkedList *p, *pre;
    for (pre = h, p = h->next; p != NULL && p->data != x; p = p->next, pre = pre->next)
        ;
    // if(p->data=x)//此判断有误,若for循环因p=NULL结束循环,则p->next出现了空指针引用
    if (p == NULL)
    {
        printf("Not found!");
        return;
    }
    //能走到此处,表示已经找到了x
    pre->next = p->next;
    free(p); // p->data数据需要删除,所以需要释放p指针
}
void find_ina(LinkedList *h, int x, int y)
{ //头结点单链表找到x在x前插入y;
    LinkedList *p, *q, *pre;
    q = newNode;
    q->data = y;
    p = h->next;
    pre = h;
    for (pre = h, p = h->next; p != NULL && p->data != x; p = p->next, pre = pre->next)
        ;
    if (p == NULL)
    {
        printf("Not found!");
        return;
    }
    q->next = p;
    pre->next = q;
}
void find_inb(LinkedList *h, int x, int y)
{ //头结点单链表找到x在x后插入y;
    LinkedList *p, *q;
    q = newNode;
    q->data = y;
    q->next = NULL;
    for (p = h->next; p != NULL && p->data != x; p = p->next)
        ;
    if (p == NULL)
    {
        printf("Not found!");
        return;
    }
    q->next = p->next;
    p->next = q;
}
void insertSorted(LinkedList *h, int x)
{ //在头结点单链表升序表中插入元素x
    LinkedList *p, *q, *pre;
    for (pre = h, p = h->next; p->data < x; p = p->next, pre = pre->next)
        ;
    q = newNode;
    q->data = x;
    q->next = NULL;
    q->next = p;
    pre->next = q;
}
void findMin(LinkedList *h)
{ //查找头结点单链表h中的最小值并将其与首元素交换
    LinkedList *p, *min;
    int temp;
    if (h->next == NULL)
        return; //若为空链表返回;
    min = h->next;
    if (min->next == NULL)
        return; //若链表只有一个元素直接返回;
    p = min->next;
    while (p != NULL)
    {
        if (p->data < min->data)
            min = p;
        p = p->next;
    }
    p = h->next; //把p改成首元素;也可以直接用h
    temp = p->data;
    p->data = min->data;
    min->data = temp;
}
void findMind(LinkedList *h)
{ //查找头结点单链表h中的最小值,并将其摘除,重新插入到链表的第一个位置
    LinkedList *prep, *p, *preMin, *min;
    if (h->next == NULL)
        return; //若为空链表直接返回;
    preMin = h;
    min = preMin->next;
    prep = h->next;
    p = prep->next;
    if (min->next == NULL)
        return; //若链表只有一个元素直接返回;
    while (p != NULL)
    {
        if (p->data < min->data)
        {
            preMin = prep;
            min = p;
        }
        p = p->next;
        prep = prep->next;
    }
    preMin->next = min->next;
    min->next = h->next;
    h->next = min;
}
LinkedList *madeup(LinkedList *h1, LinkedList *h2)
{ //将两个头结点单链表升序表合并成头结点单链表降序表;
    LinkedList *p, *q, *t;
    LinkedList *h3;
    h3 = (LinkedList *)malloc(sizeof(LinkedList)); //创建一个结点,即头结点
    h3->next = NULL;
    p = h1->next;
    q = h2->next;
    while (p != NULL && q != NULL)
    {
        if (p->data < q->data)
        {
            t = p; //贴标签
            p = p->next;
            t->next = h3->next;
            h3->next = t;
        }
        else
        {
            t = q;
            q = q->next;
            t->next = h3->next;
            h3->next = t;
        }
    }
    while (p != NULL)
    {
        t = p;
        p = p->next;
        t->next = h3->next;
        h3->next = t;
    }
    while (q != NULL)
    {
        t = q;
        q = q->next;
        t->next = h3->next;
        h3->next = t;
    }
    return h3;
}
LinkedList *madeup2(LinkedList *h1, LinkedList *h2)
{ //将两个头指针单链表升序表合并成头指针单链表降序表;
    LinkedList *p, *q, *t;
    LinkedList *h3;
    p = h1;
    q = h2;
    h3 = newNode;
    h3 = NULL;
    while (p != NULL && q != NULL)
    {
        if (p->data < q->data)
        {
            t = p; //贴标签
            p = p->next;
            t->next = h3;
            h3 = t;
        }
        else
        {
            t = q;
            q = q->next;
            t->next = h3;
            h3 = t;
        }
    }
    while (p != NULL)
    {
        t = p;
        p = p->next;
        t->next = h3;
        h3 = t;
    }
    while (q != NULL)
    {
        t = q;
        q = q->next;
        t->next = h3;
        h3 = t;
    }
    return h3;
}
LinkedList *HeBIng(LinkedList *h1, LinkedList *h2)
{ //头指针降序合成升序
    LinkedList *p, *q, *r, *h3;
    p = h1;
    q = h2;
    h3 = newNode;
    h3 = NULL;
    while (p != NULL && q != NULL)
    {
        if (p->data < q->data)
        {
            r = p;
            p = p->next;
            r->next = h3;
            h3 = r;
        }
        else
        {
            r = q;
            q = q->next;
            r->next = h3;
            h3 = r;
        }
    }
    while (p != NULL)
    {
        r = p;
        p = p->next;
        r->next = h3;
        h3 = r;
    }
    while (q != NULL)
    {
        r = q;
        q = q->next;
        r->next = h3;
        h3 = r;
    }
    return h3;
}
void madeup1(LinkedList *h1, LinkedList *h2, LinkedList *h3)
{ //将两个头结点单链表升序表合并成头结点单链表降序表;
    LinkedList *p, *q, *t;
    p = h1->next;
    q = h2->next;
    while (p != NULL && q != NULL)
    {
        if (p->data < q->data)
        {
            t = p;
            p = p->next;
            t->next = h3->next;
            h3->next = t;
        }
        else
        {
            t = q;
            q = q->next;
            t->next = h3->next;
            h3->next = t;
        }
    }
    while (p != NULL)
    {
        t = p;
        p = p->next;
        t->next = h3->next;
        h3->next = t;
    }
    while (q != NULL)
    {
        t = q;
        q = q->next;
        t->next = h3->next;
        h3->next = t;
    }
}
void delodd(LinkedList *h)
{ //头结点链表删除h中的所有奇数;
    LinkedList *pre, *p, *r;
    pre = h;
    p = h->next;
    while (p != NULL)
    {
        if (p->data % 2 == 0)
        { //判断,当p->data为偶数是,p继续往后扫描
            p = p->next;
            pre = pre->next;
        }
        //执行至此处,p标记的元素必为奇数
        else
        {
            r = p; //贴标签
            p = p->next;
            pre->next = p;
            free(r); //删除r标记的奇数
        }
    }
}
LinkedList *delodd2(LinkedList *h)
{ //头指针链表删除h中的所有奇数;
    LinkedList *pre, *p, *r;
    pre = h;
    p = h->next;
    //注意判断首元素是否为奇数,需要采用循环
    while (pre->data % 2 != 0)
    { //判断首元素是否为奇数,若为奇数删除
        r = pre;
        p = p->next;
        pre = pre->next;
        h = pre; //由于首元素已经free,所以需要移动h,不然h是野指针
        free(r);
    }
    //执行至此处pre标记的首元素为偶数
    while (p != NULL)
    {
        if (p->data % 2 == 0)
        { //判断,当p->data为偶数是,p继续往后扫描
            p = p->next;
            pre = pre->next;
        }
        //执行至此处,p标记的元素必为奇数
        else
        {
            r = p; //贴标签
            p = p->next;
            pre->next = p;
            free(r); //删除r标记的奇数
        }
    }
    return h;
}

int main()
{
    LinkedList *h, *h1, *h2, *h3;
    h1 = append2(); //创建头指针的单链表
    printf("h1=: \n");
    show2(h1);
    // printf("将头指针单链表h中的所有奇数删除\n");
    // h=delodd2(h);//注意有返回值是应采用h=delodd2(h);而不是直接delodd2(h),这样无法正确返回h
    h2 = append2();
    printf("h2=: \n");
    show2(h2);
    printf("将头指针单链表升序表h1,h2合并成降序表h3\n");
    h3 = madeup2(h1, h2);
    show2(h3);
    // h=append();//尾插法创建头结点单链表
    // h=crea_h();//头插法创建头结点单链表
    // printf("h= ");
    // show(h);
    // printf("将h中的奇数删除\n");
    // delodd(h);
    // show(h);
    // printf("将头结点单链表h中的最小值与首元素交换\n");
    // findMin(h);
    // printf("将头结点单链表h中的最小值插到表头\n");
    // findMind(h);
    // show(h);
    // printf("头结点单链表在4后面插入5\n");
    // find_in2(h,4,5);
    // show(h);
    // printf("头结点单链表删除h中的1\n");
    // find_del(h,1);
    // show(h);
    // LinkedList *h1,*h2,*h3;
    // h3=newNode;h3->next=NULL;
    // printf("请输入头结点单链表升序表h1:\n");
    // h1=append();
    // printf("h1=: ");
    // show(h1);
    // printf("请输入头结点单链表升序表h2:\n");
    // h2=append();
    // printf("h2=: ");
    // show(h2);
    // printf("将h1,h2合并成头结点单链表升序表h3\n");
    // madeup1(h1,h2,h3);
    // printf("h3=: ");
    // show(h3);
    system("pause"); //暂停批文件处理,再继续处理之前等待按任意键,需在return 0之前。
    return 0;
}

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
头插法指在链表头部插入新节点的方法,头结点单链表是在链表头部添加一个不存储数据的头结点,其目的是为了方便链表的操作。以下是头结点单链表头插法的实现代码: ```c #include <stdio.h> #include <stdlib.h> // 定义单链表节点结构体 typedef struct Node { int data; struct Node* next; } Node; // 创建头结点单链表 Node* createList() { Node* head = (Node*)malloc(sizeof(Node)); // 创建头结点 head->next = NULL; // 头结点的next指针初始化为NULL return head; } // 头插法插入新节点 void insertNode(Node* head, int data) { Node* newNode = (Node*)malloc(sizeof(Node)); // 创建新节点 newNode->data = data; // 将数据存储到新节点中 newNode->next = head->next; // 新节点的next指针指向头结点的next指针指向的节点 head->next = newNode; // 头结点的next指针指向新节点 } // 打印单链表中的所有节点 void printList(Node* head) { Node* p = head->next; // 从头结点的下一个节点开始遍历 while (p != NULL) { printf("%d ", p->data); // 输出节点中存储的数据 p = p->next; // 指向下一个节点 } } int main() { Node* head = createList(); // 创建头结点单链表 insertNode(head, 1); // 头插法插入节点 insertNode(head, 2); insertNode(head, 3); printList(head); // 打印单链表中的所有节点 return 0; } ``` 输出结果为:3 2 1,表示成功地使用头插法将3、2、1三个节点插入到了头结点单链表中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秋樱漫漫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值