数据结构:c加强训练好多题

【问题描述】假设有两个集合 A 和 B 分别用两个线性表 LA 和 LB 表示,即线性表中的数据元素即为集合中的成员。编写一个算法求一个新的集合C=A∪B,即将两个集合的并集放在线性表LC中。假设集合用顺序表存储,集合中的元素为正整数。

【输入形式】第1行输入两个集合 A 和 B的元素个数;第2行输入集合A的各数据元素;第3行输入集合B的各数据元素。

【输出形式】输出集合A和B以及并集C的各元素。

【样例输入】

        5 5

        1 2 3 4 5

        1 2 3 4 5

【样例输出】

        1 2 3 4 5

        1 2 3 4 5

        1 2 3 4 5

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

typedef int ElementType ;
typedef struct LNode
{
    ElementType data;
    struct LNode *next;
}LNode,*LinkList;

void list_tail_insert(LNode *&L,int len,LNode *(&r))
{
    L = (LNode *) malloc(sizeof(LNode));
    LNode *s;
    r=L;
    ElementType x=0;
    int i=0;
    while (i <len) {
        scanf("%d", &x);
        s = (LNode *) malloc(sizeof(LNode));
        s->data=x;
        r->next=s;
        r=s;
        i++;
    }
    r->next=NULL;
}
void merge(LinkList &L1,LinkList L2,LNode *(&r1))
{

    LNode *p=L1->next,*q=L2->next;
        while (q)
        {
            if(p->data==q->data){
                q=q->next;
                p=L1->next;
            } else{
            if(p==r1)
            {
                p=L1->next;
                r1->next=q;
                r1=r1->next;
                q=q->next;
            }
                p=p->next;
            }
        }

    r1->next=NULL;

}
void Print(LinkList L)
{
    L=L->next;
    while(L)
    {
        printf("%d ",L->data);
        L=L->next;
    }
    printf("\n");
}


int main() {
    LinkList L1,L2;
    LNode *r1,*r2;//尾指针
    int len1,len2;
    scanf("%d",&len1);
    scanf("%d",&len2);

    list_tail_insert(L1,len1,r1);
    list_tail_insert(L2,len2,r2);
    Print(L1);
    Print(L2);
    merge(L1,L2,r1);
    Print(L1);
    free(L1);
    free(L2);
    return 0;
}

【问题描述】假设有两个集合 A 和 B 分别用两个线性表 LA 和 LB 表示,即线性表中的数据元素即为集合中的成员。编写一个算法求一个新的集合C=A∩B,即将两个集合的交集放在线性表LC中。假设集合用顺序表存储,集合中的元素为正整数。  

【输入形式】第1行输入两个集合 A 和 B的元素个数;第2行输入集合A的各数据元素;第3行输入集合B的各数据元素。

【输出形式】若集合A∩B不为空,输出集合C,否则输出“交集为空”。

【样例输入】

        5 5

        1 2 3 4 5

        1 2 3 4 5

 

#include <stdio.h>

#define MaxSize 50
typedef int ElementType;

typedef struct
{
    int length;
    ElementType data[MaxSize];
}SqList;

int merge(SqList L1,SqList L2,SqList &L)
{
    int i=0,j=0,k=0;
    while (k<L1.length) {
        if(L1.data[k]==L2.data[j])
        {
            L.data[i]=L2.data[j];
            i++;
            k++;
            j=0;
        } else{
            if(j==L2.length-1){
                k++;
                j=0;
            } else{
                j++;
            }
        }

    }
    L.length=i;
    return i;
}

void PrintList(SqList L)
{
    for (int i = 0; i < L.length; i++) {
        printf("%d ",L.data[i]);
    }
    printf("\n");
}


int main() {
    SqList L1,L2,L;
    int ret;
    scanf("%d%d",&L1.length,&L2.length);
    int i;
    for ( i = 0; i < L1.length; i++) {
        scanf("%d",&L1.data[i]);

    }
    for ( i = 0; i < L2.length; i++) {
        scanf("%d",&L2.data[i]);
    }

//    PrintList(L1);
//    PrintList(L2);
    ret=merge(L1,L2,L);
    if(ret){
        PrintList(L);
    } else{
        printf("The intersection is empty");
    }
    return 0;
}

【问题描述】设计程序,该程序通过键盘输入获得整型数据a和n,计算sum=a+aa+aaa+...(共计n项),输出计算结果。
【输入形式】整形数据a和n,用空格隔开
【输出形式】求和结果
【样例输入】5 4
【样例输出】6170
【样例说明】如a=5,n=4,sum=5+55+555+5555

博主用的是递归,因为博主递归比较弱,所以想能用递归的题尽量用递归,尝试攻克它

#include <stdio.h>
int i=1,sum,temp;
int Sum(int a,int n)
{

    if(i<n)
    {

        a=a*10+temp;
        sum+=a;
        Sum(a,n-1);
        i++;
    }
    return sum;
}
int main() {
    int a,n;
    scanf("%d%d",&a,&n);
    temp=a,sum=a;
    int ret=Sum(a,n);
    printf("%d",ret);
    return 0;
}

 

【问题描述】在数组中,数字减去它右边的数字得到一个数对之差。求所有数对之差的最大值。例如
在数组{2, 4, 1, 16, 7, 5, 11, 9}中,数对之差的最大值是11,是16减去5的结果。
【输入形式】整数数组,空格隔开
【输出形式】数对之差的最大值,一个数字
【样例输入】(遇到0结束)
2 5 8 19 3 6

【样例输出】

16
【样例说明】题目要求输出数对之差的最大值,即数字减去右边数字的值,不一定为数组中最大值和最小值的差。

 

博主多写了一个只能相邻减,递归实现的

#include <stdio.h>
int find_max_duration(int *arr,int n)
{
    static int i=0,max=0,mid;
    if(i<n-1)
    {
        mid=arr[i]-arr[i+1];
        if(mid>max){
            max=mid;
        }
        find_max_duration(&arr[i+1],n-1);
    }
    return max;
}
int find_max(int *arr,int n)
{
    int i,max=0,mid,j;
    for ( i = 0; i < n; i++) {
        for ( j = i+1; j <n ; j++) {
            mid=arr[i]-arr[j];
            if(mid>max)
            {
                max=mid;
            }
        }
    }
    return max;
}
int main() {
   int b[100];
    int i=0;
    scanf("%d",b);
    while (b[i]!=0){
        i++;
        scanf("%d",&b[i]);
    }
        printf("%d ",find_max(b,i));
        printf("%d ",find_max_duration(b,i));//只能减右边的相邻


    return 0;
}

 

【问题描述】

蚂蚁王国在不断进化中,不但创建了它们自己的政府,而且选择了建立了自己的货币系统。它们对货币系统感到好奇。

传统地,一个货币系统是由1,5,10,20 或 25,50, 和 100的单位面值组成的。

蚂蚁想知道有多少种不同的方法来用货币系统中的货币来构造一个确定的数值。

举例来说, 使用一个货币系统 {1,2,5,10,...}产生 18单位面值的一些可能的方法是:18x1, 9x2, 8x2+2x1, 3x5+2+1,等等其它。

写一个程序来计算有多少种方法用给定的货币系统来构造一定数量的面值。保证总数在0 到2^63-1之间。

【输入形式】

货币系统中货币的种类数目是 V (1<=V<=25)。要构造的数量钱是 N (1<= N<=10,000)。

第一行: 二个整数,V 和 N 。

第二行:可用的货币的面值 ,以空格作为分隔符。

#include<stdio.h>
long long f[55010],money,n,m[310];
void input()
{
    int i;
    scanf("%lld%lld",&n,&money);
    for(i=1;i<=n;i++)
        scanf("%lld",&m[i]);
    return;
}
void DP()
{
    int i,j;
    f[0]=1;
    for(i=1;i<=n;i++)//处理第i种货币
    {
        for(j=m[i];j<=money;j++)//计算构造价格j方法总数
        {
            f[j]+=f[j-m[i]];//状态转移方程
        }
    }
    printf("%lld",f[money]);
    return;
}
int main()
{
    input();
    DP();
    return 0;
}

 

【问题描述】该科学记数法表示的数字一般由以下几部分构成:
1.底数部分是一个整数或小数,可能带有前缀的“+”、“-”号。如果底数带有小数点,则小数点前后必有数字。
2.字母“e”
3.指数部分是一个整数,也可能带有前缀的“+”、“-”号。
编写一个程序,将用科学记数法输入的一个数(字符串)转换成实数。
【输入形式】控制台输入用科学记数法表示的一个数,是不含空格的一行字符串。
【输出形式】输出该字符串代表的浮点数值,以默认的“%f”格式输出,保留默认的小数位数。
【样例输入】234.85e-2
【样例输出】2.348500
【样例说明】输入用科学记数法表示的一个字符串234.85e-2,输出:2.348500
【评分标准】该题要求输一个浮点数,如果你的运行结果与标准答案相差不超过0.002,则测试点得满分,否则得0分。上传C语言文件名为atoe.c。

 

#include <stdio.h>
#include <string.h>
void Num(char *a)
{
    int len= strlen(a)-1;
    int i,flag=1,flag2=1,m=0;
    double s1,s2=0.0,s3=0,s;
    if(a[0]=='-')
    {
        flag=0,m=1;

    }
    for ( i = 1; i < len; i++) {
        if(a[i]=='.')
        {
           flag2=0;
            break;
        }
    }
    int  j;
    if(flag2==0)
    {
        for ( j = m; j <i ; j++) {
            s1=s1*10.0+a[j]-48;
        }
        for ( j = i+1; j <len ; j++) {
            if(a[j]=='e')
            {
                break;
            }
            s2=s2*10.0+a[j]-48;
        }
    } else{
        for ( j = m; j <len ; j++) {
            if(a[j]=='e')
            {
                break;
            }
            s1=s1*10.0+a[j]-48;
        }
    }
    int k;
    while (s2*1.0>1)
    {
        s2=s2*1.0/10.0;
    }
    s=s1+s2;
    for ( k = j+1; k <len ; k++) {
        if(a[k]=='-')
        {
            continue;
        }
        s3=s3*10.0+a[k]-48;
    }

    int cout=0;
    if(a[j+1]=='-')
    {
        while (cout<s3){
            s=s*1.0/10;
            cout++;
        }
    } else{
        while (cout<s3){
            s=s*1.0*10;
            cout++;
        }
    }
        if(flag==0)
        {
          s=-s;
        }
    printf("%f",s);
}
int main() {
    char a[100]={0};
    fgets(a,100,stdin);
    Num(a);
//    for (int i = 0; i < strlen(a) ; ++i) {
//        printf("i=%d,val=%c ",i,a[i]);
//    }

    return 0;
}

【问题描述】设计一个程序,实现顺序表(假设顺序表的元素为整数)的基本运算。基本运算包括顺序表的初始化、创建、插入、取元素、查找、删除、输出、求长度、销毁等运算操作。

【输入形式】输入若干数据,第一行为顺序表原始数据,第二行为插入位置和插入元素值,第三行为需要取出的顺序表元素的位置,第四行为待查找元素,第五行为删除顺序表元素的位置。

【输出形式】相应操作的结果。输出共11行,前4行为元素数据、原始顺序表及其长度;第5、6行为插入操作后的结果状态及长度;第7行为取顺序表第一个元素的结果状态;第8行为查找某个数据的结果状态;第9、10行为删除操作后的结果状态,第11 行为销毁操作状态。

【样例输入1】

    47 42 15 26 92 84 59 16 18 21

    5 10

    6

    59

    5

【样例输出1】

测试结果:

原始数据:47  42  15  26  92  84  59  16  18  21  

原始顺序表L: 47 42 15 26 92 84 59 16 18 21 

  长度:10

插入后的顺序表为L: 47 42 15 26 10 92 84 59 16 18 21 

  长度:11

  第6个元素:92

查找:元素59是第8个元素

删除后的顺序表为L: 47 42 15 26 92 84 59 16 18 21 

  长度:10

销毁L

【样例输入2】

     47 42 15 26 92 84 59 16 18 21

    15 10

    16

    159

    15

【样例输出2】

测试结果:

原始数据:47  42  15  26  92  84  59  16  18  21  

原始顺序表L: 47 42 15 26 92 84 59 16 18 21 

  长度:10

插入位置非法!

  长度:10

不存在第16个元素

待查找元素159不存在!

  删除第15个元素不存在!

  长度:10

销毁L

格式真把我恶心到了

#include <stdio.h>
#define MaxSize 100
typedef int ElementType;

typedef struct
{
    int length;
    ElementType data[MaxSize];
}SqList;

bool ListInsert(SqList &L,int i,ElementType e)
{
    if(i<1||i>L.length)
    {
        return false;
    }
    if(L.length==MaxSize)
    {
        return false;
    }
    for (int j = L.length; j >=i ; j--) {
        L.data[j]=L.data[j-1];
    }
    L.data[i-1]=e;
    L.length++;
    return true;
}
bool ListDelete(SqList &L,int i,ElementType &del)
{
    if(i<1||i>L.length)
    {
        return false;
    }
    del=L.data[i-1];
    for (int j = i; j <L.length ; j++) {
        L.data[j-1]=L.data[j];
    }
    L.length--;
    return true;
}
int ListSelect(SqList L,ElementType e)
{
    //序号从1开始,所以未找到return 0;
    for (int j = 0; j <L.length ; j++) {
        if(L.data[j]==e)
        {
            return j+1;
        }
    }
    return 0;//未找到

}
void destroy(SqList &l)
{
    l.length=0;
}
void PrintList(SqList L)
{
    for (int i = 0; i < L.length; i++) {
        printf(" %d",L.data[i]);
    }
    printf("\n");
}
int main() {
    SqList L;//定义一个表
    bool ret;
    int i=0;
    ElementType e,select_e,delete_e;
    while(1) {
        scanf("%d",&L.data[i++]);
        if(getchar()=='\n')
        {
            break;
        }
    }
    int insert_po,select_po,delete_po;//设置插入位置
    scanf("%d%d",&insert_po,&e);
    scanf("%d",&select_po);//第三行为需要取出的顺序表元素的位置
    scanf("%d",&select_e);
    scanf("%d",&delete_po);
    L.length=i;
    printf("测试结果:\n原始数据:");
    int j;
    for ( j = 0; j <L.length ; ++j) {
        printf("%d  ",L.data[j]);
    }
    printf("\n原始顺序表L:");
    PrintList(L);
    printf("  长度:%d\n",L.length);
    ret= ListInsert(L,insert_po,e);
    if(ret)
    {
        printf("插入后的顺序表为L:");
        PrintList(L);
    } else{
        printf("插入位置非法!\n");
    }
    printf("  长度:%d\n",L.length);
    if(select_po<1||select_po>L.length)
    {
        printf("不存在第%d个元素\n",select_po);
    } else{
        printf("  第%d个元素:%d\n",select_po,L.data[select_po-1]);
    }
    int po=ListSelect(L,select_e);
    if(po!=0)
    {
        printf("查找:元素%d是第%d个元素\n",select_e,po);
    } else{
        printf("待查找元素%d不存在!\n",select_e);
    }
    po= ListDelete(L,delete_po,delete_e);
    if(po!=0)
    {
        printf("删除后的顺序表为L:");
        PrintList(L);

    } else{
        printf("  删除第%d个元素不存在!\n",delete_po);
    }
    printf("  长度:%d\n",L.length);
    destroy(L);
    printf("销毁L");
    return 0;
}

【问题描述】(面试题)编写一个程序,删除一个给定的有序顺序表A=(a0,a1,…an-1)中重复的元素(多个相同的元素仅保留一个)。例如a[]={1,1,2},算法执行后的结果为a[]={1,2}。假设顺序表的元素为正整数。

【输入形式】第一行为有序顺序表的长度;第2行输入任意一个有序的顺序表(其中有重复值)

【输出形式】输出删除重复值后的顺序表

【样例输入】

     3

     1 1 2        

【样例输出】

    1 2

【样例输入】

【样例说明】

【评分标准】5个评分点

#include <stdio.h>
#define MaxSize 50
typedef int ElementType;
typedef struct
{
    int length;
    ElementType data[MaxSize];
}SqList;

bool ListInsert(SqList &L,int i,ElementType e)
{
    if(i<1||i>L.length)
    {
        return false;
    }
    if(L.length==MaxSize)
    {
        return false;
    }
    for (int j = L.length; j >=i ; j--) {
        L.data[j]=L.data[j-1];
    }
    L.data[i-1]=e;
    L.length++;
    return true;
}
bool ListDelete(SqList &L,int i,ElementType &del)
{
    if(i<1||i>L.length)
    {
        return false;
    }
    del=L.data[i-1];
    for (int j = i; j <L.length ; j++) {
        L.data[j-1]=L.data[j];
    }
    L.length--;
    return true;
}
int ListSelect(SqList L,ElementType e)
{
    //序号从1开始,所以未找到return 0;
    for (int j = 0; j <L.length ; j++) {
        if(L.data[j]==e)
        {
            return j+1;
        }
    }
    return 0;//未找到

}
void PrintList(SqList L)
{
    for (int i = 0; i < L.length; i++) {
        printf("%d ",L.data[i]);
    }
    printf("\n");
}

int main() {
    SqList L;//定义一个表
    bool ret;
    ElementType e;
    scanf("%d",&L.length);
    int i;
    for ( i = 0; i <L.length ; i++) {
        scanf("%d",&L.data[i]);
    }
   // PrintList(L);
    for ( i = 0; i < L.length-1; i++) {
        while (L.data[i]==L.data[i+1]&&i < L.length-1)
        {//因为删除是覆盖,所以用while
            ListDelete(L,i+1,e);
        }
    }
    PrintList(L);
    return 0;
}

问题描述】有一个整数序列,采用顺序表L存储。设计尽可能高效的算法删除L中最大值的元素(假设这样的元素有多个)。

【输入形式】输入有一个整数序列(假设最大10000个数据)。

【输出形式】先输出“测试结果:”,然后依次输出原始数据,原始顺序表及删除后的顺序表。

【样例输入】

    2  5  4  5  4  5  3  1

【样例输出】

测试结果:

原始数据:2  5  4  5  4  5  3  1  

原始顺序表L: 2 5 4 5 4 5 3 1 

删除最大元素值后的顺序表L: 2 4 4 3 1 

死活有一个运行超时,这里的删除用的覆盖,也可以用两个表

#include <stdio.h>

#define MaxSize 10000
typedef int ElementType;


typedef struct
{
    int length;
    ElementType data[MaxSize];
}SqList;

void ListDelete(SqList &L,ElementType del)
{
    if(L.length<1)
    {
        return ;
    }
    int j,i,k=0;
    for ( j = 0,i=0; j <L.length ; j++) {
        if(L.data[j]!=del)
        {
            L.data[i++]=L.data[j];

        } else{
            L.data[i++]=L.data[++j];
            k++;
        }
    }
    L.length-=k;

}
int ListSelect(SqList L)
{
    ElementType e=L.data[0];
    int j;
    for ( j = 1; j <L.length ; j++) {
        if(L.data[j]>e)
        {
            e=L.data[j];
        }
    }
    return e;

}
void PrintList(SqList L)
{
    int i;
    for ( i = 0; i < L.length; i++) {
        printf("%d ",L.data[i]);
    }
}

int main() {
    SqList L;//定义一个表
    int i;
    char c=0;
    int temp[MaxSize];

    for(i=0;c!='\n';i++)
    {
        scanf("%d",&temp[i]);
        scanf("%c",&c);
        L.data[i]=temp[i];
    }
    L.length=i;
    printf("测试结果:\n");
    printf("原始数据:");
    int j;
    for ( j = 0; j <i ; ++j) {
        printf("%d  ",L.data[j]);
    }
    printf("\n原始顺序表L: ");
    PrintList(L);
    ElementType e=ListSelect(L);
    ListDelete(L,e);
    printf("\n删除最大元素值后的顺序表L: ");
    PrintList(L);
    return 0;
}

【问题描述】设有一个顺序表L,假设其元素均为正整数,设计一个算法将L中所有偶数删除并存到另一个顺序表L1中,而顺序表L保留原来的所有奇数。

【输入形式】输入任意一个正整数序列。

【输出形式】原始数据、原始顺序表及分离后的奇数和偶数顺序表。
【样例输入】

2  1  4  3  5  7  9  8

【样例输出】

测试结果:

原始数据:2  1  4  3  5  7  9  8  

初始顺序表L:  2 1 4 3 5 7 9 8 

拆分后:

奇数顺序表L:  1 3 5 7 9 

偶数顺序表L1: 2 4 8

#include <stdio.h>
#define MaxSize 10000
typedef int ElementType;

typedef struct
{
    int length;
    ElementType data[MaxSize];
}SqList;

void ListDivision(SqList &L,SqList& L1)
{

    if(L.length<1)
    {
        return ;
    }
    int j,i=0,k=0;
    for ( j = 0; j <L.length ; j++) {
        if(L.data[j]%2==0)
        {
            L1.data[i++]=L.data[j];
            L1.length++;

        } else{
            L.data[k++]=L.data[j];
        }
    }
    L.length-=L1.length;
}
void PrintList(SqList L)
{
    for (int i = 0; i < L.length; i++) {
        printf("%d ",L.data[i]);
    }
}

int main() {
    SqList L;
    SqList L1;
    int i=0;
    char c=0;
    int temp[MaxSize];
    for(i=0;c!='\n';i++)
    {
        scanf("%d",&temp[i]);
        scanf("%c",&c);
        L.data[i]=temp[i];
    }
    L.length=i;
    L1.length=0;
    printf("测试结果:\n");
    printf("原始数据:");
    int j;
    for ( j = 0; j <i ; ++j) {
        printf("%d  ",temp[j]);
    }

    printf("\n初始顺序表L:  ");
    PrintList(L);
    printf("\n拆分后:");
    ListDivision(L,L1);
    printf("\n奇数顺序表L:  ");
    PrintList(L);
    printf("\n偶数顺序表L1: ");
    PrintList(L1);
    return 0;

    return 0;
}

【问题描述】有一个带头结点的非空双链表L,假设所有结点值为整数.每个结点中除有prior、data和next三个域外,还有一个访问频度域freq,在链表被使用之前,其值均初始化为零。当进行LocateNodel(L,x)运算时,令元素值为x的结点中freq域的值加1,并调整表中结点次序,使其按访同频度的递减序排列,以便使频繁访问的结点总是靠近表头,采用结点移动方式设计符合上述要求的LocateNode运算的算法。

【输入形式】任意输入2行整数:第1行为双链表原始数据,据此创建双链表;第2行为查询数据序列。

【输出形式】输出创建的初始双链表及每次查询后的双链表的最新状态。
【样例输入】

1 2 3 4 5

5 5 1 0 1 2 3 1 5

【样例输出】

L: 1[0] 2[0] 3[0] 4[0] 5[0] 

查找5结点 查找后L: 5[1] 1[0] 2[0] 3[0] 4[0] 

查找5结点 查找后L: 5[2] 1[0] 2[0] 3[0] 4[0] 

查找1结点 查找后L: 5[2] 1[1] 2[0] 3[0] 4[0] 

查找0结点 0没有找到!

查找1结点 查找后L: 5[2] 1[2] 2[0] 3[0] 4[0] 

查找2结点 查找后L: 5[2] 1[2] 2[1] 3[0] 4[0] 

查找3结点 查找后L: 5[2] 1[2] 2[1] 3[1] 4[0] 

查找1结点 查找后L: 1[3] 5[2] 2[1] 3[1] 4[0] 

查找5结点 查找后L: 1[3] 5[3] 2[1] 3[1] 4[0] 

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

typedef struct DNode { //定义双链表结点类型
    int data;//数据域
    struct DNode *prior,*next;//指针域
    int freq=0;
} DNode, *DLinkList;


DLinkList Locate(DLinkList &L, int x) {

    DNode *p=L->next,*q;//p为工作指针,q为p的前驱,用于查找插入位置
    while(p&&p->data!=x)
        p=p->next;//查找值为x的结点
    if(!p) {
        return NULL;
    } else {
        p->freq++;
        if(p->next!=NULL) p->next->prior = p->prior;
        p->prior->next = p->next;//将p结点从链表上摘下
        q=p->prior;//查找p结点插入位置
        while(q!=L && q->freq<p->freq)
            q = q->prior;
        p->next = q->next;
        q->next->prior = p;
        p->prior=q;
        q->next=p;
    }
    return p;
}

//建立非循环双向链表
DLinkList CreateList_DL() {
    DNode *head, *p, *s;
    char x;
    int d;
    head = (DNode *)malloc(sizeof(DNode));
    head->prior = NULL;
    p=head;
    scanf("%d",&d);
    scanf("%c",&x);
//    scanf("%d",&x)!=EOF
    while(1) {
        s=(DNode *)malloc(sizeof(DNode));
        s->data=d;
        p->next=s;
        s->prior=p;
        p=s;
        if(x=='\n')
        {
            break;
        }
        scanf("%d",&d);
        scanf("%c",&x);


    }
    p->next = NULL;
    return head;
}

//打印非循环双向链表
void PrintList(DLinkList head) {
    DNode *p;
    p=head->next;
    while(p) {

        printf("%d[%d] ",p->data,p->freq);
        p=p->next;
    }

}



int main() {
    DLinkList L=CreateList_DL();
    printf("L: ");
    PrintList(L);
    int x[100],i=0;
//    scanf("%d",&x[i])!=EOF
   // scanf("%d",&x[i]);

    while (scanf("%d",&x[i])!=EOF)
    {
         if(Locate(L,x[i])){
             printf("\n查找%d结点 查找后L: ",x[i]);
             PrintList(L);
         } else{
             printf("\n查找%d结点 %d没有找到!",x[i],x[i]);
         }
         i++;
       // scanf("%d",&x[i]);
    }

}

 

【问题描述】有一个整数序列采用带头结点的单链表L存储。设计一个算法,删除单链表L中data值大于等于min且小于等于max的结点(若表中有这样的结点),同时释放被删结点的空间,这里min和max是两个给定的参数。

【输入形式】输入2行数据:第1行为任意整数序列(由此创建单链表),第2行为min何max

【输出形式】输出原单链表及删除后的单链表。
【样例输入】

5 1 3 6 8 2 4 8 1

3 7

【样例输出】

L: 5 1 3 6 8 2 4 8 1 

删除3~7的结点

L: 1 8 2 8 1

 

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

typedef int ElementType ;
typedef struct LNode
{
    ElementType data;//数据域
    struct LNode *next;//指针域
    //一个内容包含有数据和next指针
}LNode,*LinkList;

void list_tail_insert(LNode *&L)//LNode *和LinkList等价
{
    L = (LNode *) malloc(sizeof(LNode));//申请头节点空间
    LNode *s,*r=L;//申请新的结点,让r的地址与L地址相同,指向同一个地方,同时都指向头节点
    ElementType x;
    char c;
    scanf("%d", &x);
    scanf("%c",&c);
    while (1) {
        s = (LNode *) malloc(sizeof(LNode));
        s->data=x;
        r->next=s;
        r=s;
        if(c=='\n')
        {
            break;
        }
        scanf("%d", &x);
        scanf("%c",&c);

    }
    r->next=NULL;
}
LinkList get_elem_val(LinkList L,int search_pos)
{
    int i=0;
    if(search_pos<0){
        return NULL;
    }
    while(L&&i<search_pos)
    {
        L=L->next;//指向下一个值的地址
        i++;
    }
    return L;
}
//按值查找
int get_elem_seq(LinkList L,ElementType search_val)
{
    int i=0;
    while (L)
    {
        if(L->data==search_val){
            return i;
        }
        L=L->next;
        i++;
    }
    return -1;
}

//删除第i个位置
bool delete_elem(LinkList L,int i)//加不加引用取决与于L(首地址)会不会改变 比如头插法尾插法是为L分配空间的,形成头结点
{
    LinkList  p=get_elem_val(L,i-1);//获取i-1的地址
    if(NULL==p)
    {
        return false;
    }
    LinkList q=get_elem_val(L,i);;

    p->next=q->next;
    free(q);
    return true;
}
void Print(LinkList L)
{
    L=L->next;//L是指向头节点的,头结点里面是没有值的,所以需要从下一个结点,也就是a1开始
    while(L)
    {
        printf("%d ",L->data);
        L=L->next;
    }
    printf("\n");
}
int find_e(LinkList L,int min,int max,int a[])
{

    int i=0;
    L=L->next;//L是指向头节点的,头结点里面是没有值的,所以需要从下一个结点,也就是a1开始
    while(L)
    {
        if(L->data<=max&&L->data>=min)
        {
            a[i++]= L->data;
        }
        L=L->next;
    }
    return i;
}

int main() {
    LinkList L;
    list_tail_insert(L);//头插法
    printf("L: ");Print(L);
    ElementType min,max;
    scanf("%d%d",&min,&max);
    int a[100];
    int l=find_e(L,min,max,a);
    for (int i = 0; i < l; ++i) {
        int pos=get_elem_seq(L,a[i]);
        if(pos)
        {
            delete_elem(L,pos);
        }
    }
    printf("删除%d~%d的结点\nL: ",min,max);
    Print(L);

    return 0;
}

 

【问题描述】设计一个算法,将一个给定的带头结点的单链表L=(a0,a1,…an-1),以a0为基准,将所有小于它的元素移到该元素的前面,将所有大于等于它的元素移到该元素的后面。采用尾插法创建原始单链表(即第2行输入的每个数总是插在链表的最后一个节点)。假设链表中的数据元素均为整数。

【输入形式】第1行输入单链表长度;第2行输入单链表各个数据元素。
【输出形式】创建的原始单链表;划分后的单链表

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

typedef int ElementType ;
typedef struct LNode
{
    ElementType data;//数据域
    struct LNode *next;//指针域
    //一个内容包含有数据和next指针
}LNode,*LinkList;
int mid;
//尾插法 关键点在于L不移动 r与l地址相同
void list_tail_insert(LNode *&L)//LNode *和LinkList等价
{
    int l;
    scanf("%d", &l);
    L = (LNode *) malloc(sizeof(LNode));//申请头节点空间
    LNode *s,*r=L;//申请新的结点,让r的地址与L地址相同,指向同一个地方,同时都指向头节点
    ElementType x;
    scanf("%d", &x);
     mid=x;
    int i=0;
    while (i<l) {
        s = (LNode *) malloc(sizeof(LNode));
        s->data=x;
        r->next=s;
        r=s;
        scanf("%d", &x);
       i++;
    }
    r->next=NULL;
}

void Print(LinkList L)
{
    L=L->next;//L是指向头节点的,头结点里面是没有值的,所以需要从下一个结点,也就是a1开始
    while(L)
    {
        printf("%d ",L->data);
        L=L->next;
    }
    printf("\n");
}

void Move(LinkList &L)
{	LinkList p=L->next,pre=L;
    while (p!=NULL && p->data<0)	//跳过小于0的结点
    {      pre=p;p=pre->next;
    }
    while (p!=NULL)
    {	if (p->data<mid)			//若*p结点值小于0
        {	pre->next=p->next;	//从链表中删除*p结点
            p->next=L->next;	//将*p结点插入到头结点之后
            L->next=p;
            p=pre->next;		//p指向*pre之后结点,pre不变
        }
        else					//若*p结点值不小于0
        {	pre=p;				//pre、p同步后移一个结点
            p=p->next;
        }
    }
}

int main() {
    LinkList L;
    list_tail_insert(L);//尾插法
     Print(L);
    Move(L);
    Print(L);

    return 0;
}

【问题描述】设计一个算法逆置一个单链表。如(1,2,3,4,5)逆置为(5,4,3,2,1)。

【输入形式】输入任意一个正整数序列。

【输出形式】原始单链表及逆置后的单链表。

【样例输入】

 1 2 3 4 5   
【样例输出】

原链表为:

1 2 3 4 5

逆置后的链表为:

5 4 3 2 1


#include <stdio.h>

#include <cstdlib>

typedef int ElemType;
typedef struct LNode        //定义单链表结点类型
{
    ElemType data;
    struct LNode *next;     //指向后继结点
}LinkList;
void CreateListR(LinkList *&L,ElemType a[],int n)//尾插法建立单链表
{
    LinkList *s,*r;
    int i;
    L=(LinkList *)malloc(sizeof(LinkList));     //创建头结点
    L->next=NULL;
    r=L;                    //r始终指向终端结点,开始时指向头结点
    for (i=0; i<n; i++)
    {
        s=(LinkList *)malloc(sizeof(LinkList));//创建新结点
        s->data=a[i];
        r->next=s;          //将*s插入*r之后
        r=s;
    }
    r->next=NULL;           //终端结点next域置为NULL
}
void DestroyList(LinkList *&L)
{
    LinkList *p=L,*q=p->next;
    while (q!=NULL)
    {
        free(p);
        p=q;
        q=p->next;
    }
    free(p);    //此时q为NULL,p指向尾结点,释放它
}
void DispList(LinkList *L)
{
    printf("\n");
    LinkList *p=L->next;
    while (p!=NULL)
    {
        printf("%d ",p->data);
        p=p->next;
    }
    printf("\n");
}

void Reverse(LinkList *&L)
{
    LinkList *p=L->next,*q;
    L->next=NULL;
    while (p!=NULL)     //扫描所有的结点
    {
        q=p->next;      //让q指向*p结点的下一个结点
        p->next=L->next;    //总是将*p结点作为第一个数据结点
        L->next=p;
        p=q;            //让p指向下一个结点
    }
}
int main()
{
    LinkList *L;
    int a[1000],i=0;
    while (scanf("%d",&a[i])!=EOF)
    {
        i++;
    }
    CreateListR(L,a,i);
    if(L->next){
        printf("原链表为:");
        DispList(L);
        Reverse(L);
        printf("逆置后的链表为:");
        DispList(L);
    } else{
        printf("原链表为:\n空链表!");
        printf("\n逆置后的链表为:\n空链表!");
    }

    DestroyList(L);
    return 0;
}

【问题描述】输入n个整数,创建一个双向循还链表表进行存储,这些整数从第二个结点至表尾递增有序(设a1<x<an-1) (链表中第i个元素其值为ai  )。试编写程序,将第一个结点删除并插入表中适当位置,使整个链表递增有序
【输入形式】先输入数据的个数,再输入数据
【输出形式】依次输出数据
【样例输入】5 3 1 2 4 5
【样例输出】1 2 3 4 5
【样例说明】输入数据的第一个数是整数的个数,其后是数据
【评分标准】根据输入的数据创建循环链表,并把原来部分有序的链表处理成有序的链表并输出

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


#define ElemType int

typedef struct listNode {
    ElemType data;
    struct listNode* llink, * rlink;
}List, * DoubleList;

/*初始化双向链表*/
void InitList(DoubleList* L) {
    *L = (List*)malloc(sizeof(List));
    (*L)->rlink = NULL;
    (*L)->llink = NULL;
}


void Creatlist(DoubleList L, int n) {
    List* r, * s;
    ElemType c;
    r = L;
    while (n--) {
        scanf("%d\n",&c);
        s = (List*)malloc(sizeof(List));
        s->data = c;
        r->rlink = s;
        s->llink = r;
        r = s;
    }
    r->rlink = L;
    L->llink = r;
}

void Insert(DoubleList L, ElemType e) {
    List* s, * p;
    for (p = L->rlink; p != L && p->data < e; p = p->rlink)
        ;
    s = (List*)malloc(sizeof(List));
    s->data = e;
    s->llink = p->llink;
    p->llink->rlink = s;
    p->llink = s;
    s->rlink = p;
    return;
}

void Delete(DoubleList L, int i, ElemType* e) {
    List* p;
    int k = 0;
    p = L;
    while (p->rlink != L && k < i) {
        p = p->rlink;
        k++;
    }

    *e = p->data;
    p->llink->rlink = p->rlink;
    p->rlink->llink = p->llink;
    free(p);
    return;
}

void show(DoubleList L) {
    List* s;
    s = L->rlink;
    while (s != L) {
        printf("%d ",s->data);
        s = s->rlink;
    }

}


int main()
{
    DoubleList L;
    int len;
    InitList(&L);
    scanf("%d",&len);
    Creatlist(L, len);

    /*删除操作*/
    ElemType tmp2;
    Delete(L, 1, &tmp2);

    /*插入操作*/
    Insert(L, tmp2);
    show(L);

    return 0;
}


【问题描述】(面试题)设计一个算法,求非空单链表的中间结点。如(1,2,3,4,5)的中间位置结点是3(元素个数为奇数),(1,2,3,4)的中间位置结点是2(元素个数为奇数)。采用尾插法创建原始单链表(即第2行输入的每个数总是插在链表的最后一个节点)。假设链表中的数据元素均为整数。

【输入形式】第1行输入单链表长度;第2行输入单链表各个数据元素。

【输出形式】创建的原始单链表;划分后的单链表
【样例输入】

【问题描述】(面试题)设计一个算法,求非空单链表的中间结点。如(1,2,3,4,5)的中间位置结点是3(元素个数为奇数),(1,2,3,4)的中间位置结点是2(元素个数为奇数)。采用尾插法创建原始单链表(即第2行输入的每个数总是插在链表的最后一个节点)。假设链表中的数据元素均为整数。
【输入形式】第1行输入单链表长度;第2行输入单链表各个数据元素。
【输出形式】创建的原始单链表;划分后的单链表
【样例输入】

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值