设有一个正整数序列组成的有序单链表(按递增次序有序,且允许有相等的整数存在),试编写能实现下列功能的算法 :(要求用最少的时间和最小的空间)

设有一个正整数序列组成的有序单链表(按递增次序有序,且允许有相等的整数存在),试编写能实现下列功能的算法 :(要求用最少的时间和最小的空间)

(1)确定在序列中比正整数x大的数有几个(相同的数只计算一次,如序列{20,20,17,16,15,15,11,10,8,7,7,5,4}中 比10大的数有5个);
(2)在单链表将比正整数x小的数按递减次序排列;
(3)将正整数比x大的偶数从单链表中删除。

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

typedef int ElemType;
typedef struct node
{
        ElemType data;
        struct node *next;
} Node, *LinkList;

int Count(LinkList L, int x);//计算比x大的数的个数
void DisplayList(LinkList L);//打印链表
void Reverse(LinkList *L, int x);//把比x小的序列倒置
void Delete_Than(LinkList *L, int x);//删除比x大的偶数
int main()
{
        int input;
        LinkList L = NULL;
        LinkList node;
        printf("请按升序输入一串数,中间以空格间隔,以-1结尾\n");
        scanf("%d", &input);
        while(1)
        {
                static LinkList tail;//静态定义一个尾指针
                node = (LinkList)malloc(sizeof(Node));
                node ->data = input;
                if(L == NULL)
                {
                        L = node;
                        node->next  = NULL;
                }
                else
                {
                        tail->next = node;
                        node->next = NULL;
                }
                tail = node;
          		/********************上为尾插法*******************/
                scanf("%d", &input);
                if(input == -1)
                        break;//输入-1时,结束循环
                while(input < tail->data)
                {
                        printf("输入错误,重新输入输错的部分\n");
                        scanf("%d", &input);
                }//如果输入的值小于前一个数,则输入错误
        }
        printf("现在的链表为\n");
        DisplayList(L);
        
        int x;//确定x
        printf("请输入x\n");
        scanf("%d", &x);
        int a = Count(L, x);
        printf("比x大的数共%d个\n", a);
        printf("现在倒置比x小的数据\n");
        Reverse(&L, x);
        printf("现在的链表为\n");
        DisplayList(L);
        printf("现在删除比x大的偶数\n");
        Delete_Than(&L,x);
        printf("现在的链表为\n");
        DisplayList(L);
        return 0;
}
void DisplayList(LinkList L)
{
        LinkList node = L;
        while(node != NULL)
        {
                printf("%d ", node->data);
                node = node->next;
        }
        printf("\n");
}
void Reverse(LinkList *L, int x)
{
        LinkList r = *L;
        LinkList p = *L;
        LinkList q = NULL;
        while(p->data < x)
        {
                q = p;
                p = p->next;
        }//此时,p是x所在结点或比x小的第一个节点,q为p的前节点
        
        /*p->data是否等于a会有不同的插入,可画图进行深刻了解*/
        if(p->data == x)
        {
                while(*L != q)
                {
                        *L = (*L)->next;//头结点后移
                        r->next = q->next;//r为头结点,把头结点插入到q的后面
                        q->next = r;//
                        r = *L;//再把r指向头结点
                }
        }
        else//p->data小于x时
        {
                while(*L != p)
                {
                        *L = (*L)->next;//头结点后移
                        r ->next = p->next;//把头结点插入到p后
                        p->next = r;
                        r = *L;//再把r指向头结点
                }
        }
}
int Count(LinkList L, int x)
{
        int  num =  0;
        int e;//取出比x大的数
        LinkList p = L;
        while(p->data <= x)
        {
                p = p->next;
        }//此时,p->data大于x
        e = p->data;取出此时的p->data
        num++;计数器加一
        p = p->next;//指向下个节点
        while(p)
        {
                if(p->data > e)//判断p->data > e的时候
                {
                        e = p->data;//取出e;
                        num++;计数器加1
                }
                p = p->next;//指向下个节点
        }
        return num;//返回比x大的数的个数
}
//删除比x大的偶数
void Delete_Than(LinkList *L, int x)
{
        LinkList q = NULL;
        LinkList p = *L;
        while(p->data <= x)
        {
                q = p;
                p = p->next;
        }//p指向比x大的节点,q为p的前节点
        while(p)
        {
                if(p->data % 2 == 0)//判断p->data是比x大的偶数
                {
                        LinkList  temp = p;//先把p赋给temp;
                        q->next   =  p->next;//删除p节点
                        p = q->next;//把q的下个节点赋给p
                        free(temp);//释放空间
                }
                else//不是偶数
                {
                		//两个指针后移
                        q = q->next;
                        p = p->next;
                }
        }
}
  • 18
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值