数据结构算法——链表(1)单链表

单链表默认的结构体

typedef struct LNode{
    int data;
    struct Node *next;
}LNode;


1.分别采用头插法和尾插法建立一个带头结点的单链表

LNode* tail_insert()
{
    int x;
    scanf("%d",&x);
    LNode* L=(LNode*)malloc(sizeof(LNode));
    LNode* r=L;
    while(x!=99999)
    {
        LNode* s=(LNode*)malloc(sizeof(LNode));
        s->data=x;
        s->next=NULL;
        r->next=s;
        r=s;//r=r->next;
        scanf("%d",&x);
    }
    return L;

}

思想:

先设置变量存储数据。

建立L头节点,将头节点赋于r用来遍历。

当x不是9999时循环一直继续,可以一直进行插入。

动态存储一个s节点,将x保存到s data因为尾插所以s后面为NULL。

前面指针还未指向,L和s中间指针仍然需要指向,要因为我们用r存储了L所以直接将r指针指向后面的s就行。同时不断更新r的位置(将s的位置赋于r,相当于每次r在s之前)从而能够实现指针的指向。

尾插法

LNode* head_create()
{
    LNode*L=(LNode*)malloc(sizeof(LNode));
    L->next=NULL;
    int x;
    scanf("%d",&x);
    while(x!=9999)
    {
        LNode*s=(LNode*)malloc(sizeof(LNode));
        s->data=x;
        s->next=L->next;
        L->next=s;
        scanf("%d",&x);
    }
    return L;
}

思想:

建立头节点

输入x当为9999时停止循环

建立节点,将数据赋值给s。

插入节点相当于插入到L和L后一个节点中间。我们需要将L指向新的节点,新的节点指向L后的那个第一个节点。


2.一个带头结点的链表,申请一个值为x的空间,插入L仍然递增有序

LNode* insert_x(LNode*&L,int x)
{
    LNode *s=L;
    while(s->next!=NULL)
    {
        if(s->next->data>x)    
        {
            LNode*p=(LNode*)malloc(sizeof(LNode));
            p->data=x;
            LNode*r=s->next;
            p->next=r;
            s->next=p;
        }
        s=s->next;
    }
}

思想:

进行循环若s下一个不为空则还有数据。

判断s中每个与x大小,找到第一个比x大的数据。(用s->next原因,因为s一开始是头指针不保存数据)

找到之后,我们建立新节点,将新节点插入到这两之间。

可知s->next为我们找到那个指针,s就是前面的因而我们也可以直接写(p->next=s->next;s->next=p;)也可以。

若为找到s继续往后。


3.删除单链表第一个为x元素

void del_x(LNode*&L,int x)
{
    LNode* p=L;
    while(p->next!=NULL)
    {
        if(p->next->data==x)
        {
            LNode*r=p->next;
            p->next=r->next;
            free(r);
            break;
        }
        p=p->next;
    }
}

思想:

建立节点从开始往后遍历,若不为x继续遍历,若为x则进行指针删除并且中止

由于p->next数据是x,我们只需将p指向p->next->next并且释放p->next即可,我这里用了r去替换p->next是一样的。


4.删除所有x的元素

void del_x(LNode*&L)
{
    LNode*p=L;
    while(p->next!=NULL)
    {
        if(p->next->data==x)
        {
            Lode* r=p->next;
            p->next=r->next;
            free(r);
        }
        p=p->next;
    }
}

思想:

同3只是不用中止。


5.带头结点链表就位逆置

void reverse(LNode*&L)
{
    LNode*p=L->next;
    L->next=NULL;
    while(p!=NULL)
    {    
        r=p->next;
        p->next=L->next;
        L->next=p;
        p=r;
    }
}

思想:

相当于新建一个头节点为L,L的下一个为NULL。由此可见我们将会对L->next进行修改,我们需要将其先进性保存。

当不为空循环(为什么不是p->next,因为我们用了r保存了p->next,在最后一步时已经时p->next了,所以用p即可)。

同理我们后面也对p->next修改了因而要提前进行保存。后续相当于头插。


6.删除最小的元素

bool del_min(LNode*&L)
{
    LNode* s=L,*pose=L;
    while(s->next!=NULL)
    {
        if(s->next->data<pose->next->data)
        {
            pose=s;
        }
        s=s->next;
    }    
     LNode *r=pose->next;
     pose->next=r->next;
     free(r);
}

思想:

设置两个变量一个pose另一个s

pose用来保存最小元素的前一个位置。

若s下一个不为空则继续遍历,如果s比pose小将s赋值给pose

最后将pose->next即最小元素删除。将pose->next前后两个指针相连。


7.按照递增有序输出所有点并释放空间

void print_elem(LNode*&L)
{
    LNode*pose=L,*s=L;
    while(L->next!=NULL)
{
    while(s->next!=NULL)
    {
        if(s->next->data<pose->next->data)
        {
            pose=s;
        }
        s=s->next;
    }
    LNode*r=pose->next;
    pose->next=r->next;
    printf("%d\n",r->data);
    free(r);
}   
}

思想:

不断地查找最小值,因而最外环中止即头节点下一个是否为空,这时所有元素全部释放了。

在同6不断释放最小元素,记得打印即可。


8.将一个带头结点单链表最小元素移动到最前面

void move_min(LNode*&L)
{
    LNode*pose=L,*s=L;
    while(s->next!=NULL)
    {
        if(s->next->data<pose->next->data)
        {pose=s;}
        s=s->next;
    }
    LNode*r=pose->next;
    pose->next=r->next;
    r->next=L->next;
    L->next=r;
}

思想:

先找到最小的元素不用将其释放,将最小元素前指针和后指针连在一起。

最后将这个节点头插到头节点和第一个元素之间。


9.设有一个无序的链表编写以下功能1.找出最小值2.若为奇数则与后继点交换3.偶数则删除后继节点

void func(LNode*&L)
{
    LNode*pose=L,*s=L;
    while(s->next!=NULL)
    {
        if(s->next->data<pose->next->data)
        {
            pose=s;
        }
        s=s->next;
    }
    LNode*u=pose->next;
    LNode*r=r->next;
    u->next=r->next;
    if(u->data%2==0)
    {
        free(u);
    }
    else
    {
        r->next=pose->next;
        pose->next=u->next;
    }
}

思想:

先找到最小值,然后进行判断奇数偶数

不管插入还是交换次序,我们都可以先将pose->next位置和他next的next进行两个指针相连。

若为偶数直接free释放

交换次序将pose->next赋于r->nex,将r指向pose后一个节点

在连接前面节点把u->next(相当于r)赋给pose->next

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值