【C语言】单链表常见算法

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

typedef struct LNode
{
    int data;
    struct LNode *next;
} LNode, *Linklist;

// 单链表的遍历
void LinklistPrint(Linklist L)
{
    Linklist p = L->next;
    while (p != NULL)
    {
        printf("%d ", p->data);
        p = p->next;
    }
}

// 单链表的按位查找
Linklist Search_by_pos(Linklist L, int pos)
{
    if (pos < 1)
        return NULL;
    int cur = 1;
    Linklist p = L->next;
    while (p != NULL && cur < pos)
    {
        p = p->next;
    }
    return p;
}

// 单链表的按值查找
Linklist Search_by_num(Linklist L, int e)
{
    Linklist p = L->next;
    while (p != NULL && p->data != e)
    {
        p = p->next;
    }
    return p;
}

// 头插法建立单链表
Linklist CreateHeadLinklist(Linklist *L)
{
    (*L) = (Linklist)malloc(sizeof(LNode)); // 带头结点
    (*L)->next = NULL;
    Linklist temp;
    int e;
    scanf("%d", &e);
    while (e != -1)
    {
        temp = (Linklist)malloc(sizeof(LNode));
        temp->data = e;
        temp->next = (*L)->next;
        (*L)->next = temp;
        scanf("%d", &e);
    }
    return (*L);
}

// 尾插法建立单链表
Linklist CreateTailLinklist(Linklist *L)
{
    (*L) = (Linklist)malloc(sizeof(LNode));
    (*L)->next = NULL;
    Linklist r = (*L), temp;
    int e;
    scanf("%d", &e);
    while (e != -1)
    {
        temp = (Linklist)malloc(sizeof(LNode));
        temp->data = e;
        temp->next = NULL;
        r->next = temp;
        r = temp;
        scanf("%d", &e);
    }
    r->next = NULL;
    return (*L);
}

// 单链表原地逆置
void Reverse(Linklist *L)
{
    Linklist p = (*L)->next;
    Linklist r;
    (*L)->next = NULL;
    while (p != NULL)
    {
        r = p->next;
        p->next = (*L)->next;
        (*L)->next = p;
        p = r;
    }
}

// 将单链表A分解成2个带头结点的单链表A,B,
// 且A中含原链表奇数项元素,B表含原表偶数项元素,相对顺序不变,返回B表
Linklist Divide_A_and_B(Linklist *A)
{
    Linklist B = (Linklist)malloc(sizeof(LNode));
    B->next = NULL;
    Linklist ra = (*A);
    Linklist rb = B;
    Linklist p = (*A)->next;
    (*A)->next = NULL;
    while (p != NULL)
    {
        ra->next = p;
        ra = p;
        p = p->next;
        if (p != NULL)
        {
            rb->next = p;
            rb = p;
            p = p->next;
        }
    }
    ra->next = NULL;
    rb->next = NULL;
    return B;
}

// 将A={a1,b1,a2,b2....,an,bn}拆分成2个带头结点的单链表A,B
// 使得A={a1,a2,...,an},B={bn,...,b2,b1};
Linklist Divide_A_and_B2(Linklist *A)
{
    Linklist p = (*A)->next;
    Linklist ra = (*A);
    Linklist B = (Linklist)malloc(sizeof(LNode));
    B->next = NULL;
    Linklist rb;
    while (p != NULL)
    {
        ra->next = p;
        ra = p;
        p = p->next;
        if (p != NULL)
        {
            rb = p;
            p = p->next;
            rb->next = B->next;
            B->next = rb;
        }
    }
    ra->next = NULL;
    return B;
}
// 将单链表A,B有序合并成1个A
void Merge(Linklist *A, Linklist *B)
{
    Linklist p = (*A)->next;
    Linklist q = (*B)->next;
    Linklist r;
    (*A)->next = NULL;
    while (p != NULL && q != NULL)
    {
        if (p->data < q->data)
        {
            r = p->next;
            p->next = (*A)->next;
            (*A)->next = p;
            p = r;
        }
        else
        {
            r = q->next;
            q->next = (*A)->next;
            (*A)->next = q;
            q = r;
        }
    }
    if (p != NULL)
    {
        p = q;
    }
    while (p != NULL)
    {
        r = p->next;
        p->next = (*A)->next;
        (*A)->next = p;
        p = r;
    }
    free(B);
}

// 找到链表最小值并删除
void FindMin(Linklist *L)
{
    Linklist pre = (*L), p = (*L)->next;
    Linklist minpre = pre, minp = p;
    while (p != NULL)
    {
        if (p->data < minp->data)
        {
            minp = p;
            minpre = pre;
        }
        pre = p;
        p = p->next;
    }
    minpre->next = minp->next;
    free(minp);
}

// 删除单链表中所有值为x的结点
void Delete_x(Linklist *L, int x)
{
    Linklist pre = *L;
    Linklist p = pre->next;
    while (p != NULL)
    {
        if (p->data == x)
        {
            pre->next = p->next;
            free(p);
            p = pre->next;
        }
        else
        {
            pre = p;
            p = p->next;
        }
    }
}
// 删除单链表中所有值介于两个给定值之间的结点
void Delete_between_x_t(Linklist *L, int x, int t)
{
    Linklist pre = (*L);
    Linklist p = pre->next;
    while (p != NULL)
    {
        if (p->data <= t && p->data >= x)
        {
            pre->next = p->next;
            free(p);
            p = pre->next;
        }
        else
        {
            pre = p;
            p = p->next;
        }
    }
}
// 删除一个有序单链表中值重复的结点
void Delete_Repeat(Linklist *L)
{
    Linklist pre = (*L)->next;
    Linklist p = pre->next;
    while (p != NULL)
    {
        if (p->data == pre->data)
        {
            pre->next = p->next;
            free(p);
            p = pre->next;
        }
        else
        {
            pre = p;
            p = p->next;
        }
    }
}
// 找出2个递增有序的单链表中值相同的结点,生成单链表c
Linklist FindSameAB(Linklist *A, Linklist *B)
{
    Linklist p = (*A)->next;
    Linklist q = (*B)->next;
    Linklist C = (Linklist)malloc(sizeof(LNode));
    Linklist rc = C, temp;
    while (p != NULL && q != NULL)
    {
        if (p->data < q->data)
        {
            p = p->next;
        }
        else if (p->data > q->data)
        {
            q = q->next;
        }
        else
        {
            temp = (Linklist)malloc(sizeof(LNode));
            temp->data = p->data;
            temp->next = NULL;
            rc->next = temp;
            rc = temp;
        }
    }
    return C;
}

// 求2个递增有序的单链表的交集并放入A中,释放其他空间
Linklist FindCro(Linklist *A, Linklist *B)
{
    Linklist p = (*A)->next;
    Linklist q = (*B)->next;
    Linklist ra = (*A);
    Linklist temp;
    while (p != NULL && q != NULL)
    {
        if (p->data < q->data)
        {
            temp = p;
            p = p->next;
            free(temp);
        }
        else if (p->data > q->data)
        {
            temp = q;
            q = q->next;
            free(temp);
        }
        else
        {
            ra->next = p;
            ra = p;
            p = p->next;
            temp = q;
            q = q->next;
            free(q);
        }
    }
    if (q != NULL)
    {
        p = q;
    }
    while (p != NULL)
    {
        temp = p;
        p = p->next;
        free(temp);
    }
}

// 有一头指针为head的单链表,按递增次序输出结点,并删除
void PrintLinklist(Linklist *head)
{
    while ((*head)->next != NULL)
    {
        Linklist pre = (*head);
        Linklist minpre = pre;
        Linklist p = pre->next;
        Linklist minp = p;
        while (p != NULL)
        {
            if (p->data < minp->data)
            {
                minp = p;
                minpre = pre;
            }
            pre = p;
            p = p->next;
        }
        minpre->next = minp->next;
        printf("%d", minp->data);
        free(p);
    }
}

// 判断B链表是否是A链表的连续子序列
int JudgeBA(Linklist A, Linklist B)
{
    Linklist p = A->next;
    Linklist q = B->next;
    Linklist pre = A->next;
    while (p != NULL && q != NULL)
    {
        if (p->data == q->data)
        {
            p = p->next;
            q = q->next;
        }
        else
        {
            p = pre->next;
            pre = p;
            q = B->next;
        }
    }
    return (q == NULL) ? 1 : 0;
}

// 判断单链表是否有环
int IsLoop(Linklist L)
{
    Linklist fast = L->next;
    Linklist slow = L->next;
    while (fast != NULL && fast->next != NULL)
    {
        fast = fast->next->next;
        slow = slow->next;
        if (fast == slow)
        {
            return 1;
        }
    }
    return 0;
}
// 链接2个不带头结点的循环单链表,将h2链接到h1后
Linklist ConbLink(Linklist *h1, Linklist *h2)
{
    Linklist rh1 = (*h1), rh2 = (*h2);
    while (rh1->next != h1)
    {
        rh1 = rh1->next;
    }
    while (rh2->next != h2)
    {
        rh2 = rh2->next;
    }
    rh1->next = h2;
    rh2->next = h1;
    return h1;
}
// 递增次序输出循环单链表的各结点并删除,直至单链表为空,再删除头结点
void Delete_print(Linklist *L)
{

    while ((*L)->next != (*L))
    {
        Linklist p = (*L)->next;
        Linklist pre = (*L);
        Linklist minpre = (*L), minp = (*L)->next;
        while (p->next != (*L))
        {
            if (p->data < minp->data)
            {
                minp = p;
                minpre = pre;
            }
            else
            {
                pre = p;
                p = p->next;
            }
        }
        printf("%d", minp->data);
        minpre->next = minp->next;
        free(minp);
    }
    free(*L);
}

// 判断带头结点的循环双链表L是否对称
typedef struct DNode
{
    int data;
    struct DNode *prior, *next;
} DNode, *DLinklist;

int Fuc(DLinklist L)
{
    DNode *p = L->next, *q = L->prior;
    while (p != q && q->next != p)
    {
        if (p->data == q->data)
        {
            p = p->next;
            q = q->prior;
        }
        else
        {
            return 0;
        }
    }
    return 1;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值