C:十四道练习题(仅c,没有c++)

10.使用选择排序法,对输入数组进行排序
【输入形式】

整型数组A
【输出形式】

排序后的数组
【样例输入】

2 4 6 8 3 8 5 9
【样例输出】

2 3 4 5 6 8 8 9
【样例说明】

#include <stdio.h>
void Print(int  s[],int l)
{
    int i;
    for ( i = 0; i <l; ++i) {
        printf("%d ",s[i]);
    }
    printf("\n");
}
void select_sort(int  s[],int l)
{
    int i,j;
    int min;
    for ( i = 0; i < l-1; i++) {
        min=i;
        for ( j = i+1; j <l ; j++) {
            if(s[j]<s[min])
            {
                min=j;
            }
        }
        int temp=s[i];
        s[i]=s[min];
        s[min]=temp;
    }
}

int main() {
    int i=0;
    int t;
    int temp[50];
    while (scanf("%d",&t)!=EOF) {
        temp[i++]=t;
    }

    select_sort(temp,i);
    Print(temp,i);
    return 0;
}

1.【问题描述】利用快速排序思想实现一系列1000以内的正整数的排序。(备注:总数据量不超过200。样例输出中的count=7表示总共进行了7趟排序!)  提示:统计次数可以使用静态局部变量
【输入形式】输入若干1000以内的正整数,-1结束输入。
【输出形式】先输出排序前的原始数据,再输出最后输出排好序的结果
【样例输入】

6 8 7 9 0 1 3 2 4 5 -1

【样例输出】

before:6 8 7 9 0 1 3 2 4 5

after:0 1 2 3 4 5 6 7 8 9


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

typedef int ElemType;
typedef struct {
    ElemType * elem;//存,申请的空间的首地址
    int tab_length;//存储动态数组里元素的个数
}SSTable;
void ST_Init(SSTable *t,int len) {
    (*t).tab_length=len;//元素个数,数组长度
    (*t).elem = (ElemType *) malloc(sizeof(ElemType)*(*t).tab_length);

}
void Print(SSTable s)
{
    int i;
    for ( i = 0; i <s.tab_length ; ++i) {
        printf("%d ",s.elem[i]);
    }
    printf("\n");
}

int  partition(ElemType  *a,int low,int high)
{
    int pivot=a[low];
    while (low<high) {
        while ( low<high&&pivot<=a[high])
        {
            high--;
        }
        a[low]=a[high];
        while ( low<high&&pivot>=a[low])
        {
            low++;
        }
        a[high]=a[low];
    }
    a[low]=pivot;
    return low;
}
void Quick_sort(SSTable *s,int low,int high)
{
if(low<high)
{
int pivot= partition((*s).elem, low, high);//保存分割点
Quick_sort(s, low, pivot-1);
Quick_sort(s, pivot+1, high);
}

}
int main() {
    SSTable t;
    ST_Init(&t,200);
    int len=0,cc;
    scanf("%d",&cc);
    while (cc!=-1)
    {
        t.elem[len++]=cc;
        scanf("%d",&cc);
    }
    t.tab_length=len;
    int low=0,high=len-1;//数组长度,,index最大len-1
    printf("before:");
    Print(t);
    Quick_sort(&t,low,high);
    printf("after:");
    Print(t);
    free(t.elem);
    return 0;
}

3.【问题描述】编写一个程序,当在一个字符串中出现子串时就删除它。
【输入形式】用户在第一行输入一个字符串,用户在第二行输入一个子串。
【输出形式】程序在下一行输出删除其中所有子串后的字符串。如果字符串不包含子串则输出原字符串本身。
【样例输入】
 I am a boy!
 a             
【样例输出】
 I m  boy!       
【样例说明】用户首先输入字符串I am a boy!,然后输出子串a,程序会寻找字符串中的子串删除它,最后   将删除后的结果输出:I#m##boy!   #表示空格。
【评分标准】结果完全正确得20分,每个测试点4分。提交程序名为:delsubstring.c

#include <stdio.h>
#include <string.h>

int main(void)
{
    char s1[81]={0};
    char s2[81]={0};
    char temp[81]={0};

    gets(s1);//gets函数读取一行输入,直到遇到回车
    gets(s2);
    while(strstr(s1,s2)!=NULL){//strstr函数用于判断s1中是否含有s2子串
        int len1=strlen(s1);
        int len2=strlen(s2);
        strcpy(temp,strstr(s1,s2));
        int lentemp=strlen(temp);
        strcpy(s1+len1-lentemp,temp+len2);//计算出具体需要操作位置的起始与终止地址
    }
    puts(s1);

    return 0;
}

4.【问题描述】编写一个程序,将两个元素从小到大有序的一维数组归并成一个有序的一维数组。
【输入形式】用户在第一行输入第一个有序数组的元素数目,以回车结束此输入。然后在第二行按照刚才输入的元素数目依次输入数组元素,中间用空格分隔,最后用回车结束输入。第三行和第四行只需重复刚才的步骤,将第二个有序数组也输入即可。输入时候一定是有序输入的,即数组元素已经按照从小到大顺序排列。
【输出形式】程序将两个有序一维数组合并为一个有序数组并按照从小到大顺序输出。每个元素输出时用空格分隔,最后一个输出之后没有空格。
【样例输入】
6
2 5 8 11 20 35
4
1 6 15 60                     
【样例输出】1 2 5 6 8 11 15 20 35 60
【样例说明】第一行输入为第一个有序数组的元素数目,第二行为有序数组元素;第三行为第二个有序数组的元素数目,第四行为有序数组元素。
【评分标准】结果完全正确得20分。提交程序名为:arraysort.c

#include<stdio.h>

void merge(int a[],int b[],int c[],int l1,int l2,int len)
{
    int p=0,q=0,i;
    for ( i = 0; i < len&&p<l1&&q<l2; ++i) {
        if(a[p]<b[q])
        {
            c[i]=a[p++];
        } else{
            c[i]=b[q++];
        }
    }
    while (p<l1)
    {
        c[i++]=a[p++];
    }
    while (q<l2)
    {
        c[i++]=b[q++];
    }

}
int main() {
    int l1,l2,i=0;
    scanf("%d",&l1);
    int a[l1];
    while (i<l1)
    {
        scanf("%d",&a[i++]);
    }
    scanf("%d",&l2);
    int b[l2];
    i=0;
    while (i<l2)
    {
        scanf("%d",&b[i++]);
    }
    int len=l1+l2;
    int c[len];
    merge(a,b,c,l1,l2,len);
    int j;
    for ( j = 0; j < len; j++) {
        printf("%d", c[j]);
        if(j!=len-1)
        {
            printf(" ");
        }
    }
    return 0;
}

12.【问题描述】已知具有n个数组元素的一维数组A,请写一个算法,将该数组中所有值为0的元素都依次移到数组的前端,其他元素依次输出。
【输入形式】第一个数为输入数字的个数,其后为数组的数字
【输出形式】输出相应的数组
【样例输入】5 1 2 3 4 0
【样例输出】0 1 2 3 4

#include<stdio.h>
int main() {
 int n,i=0,count=0;
    scanf("%d",&n);
    int a[n],b[n];
    while (i<n)
    {
        scanf("%d",&a[i]);
        if(a[i]==0)
        {
            count++;
        }
        i++;
    }
    int j;
    //脏数据
    for ( j = 0; j < count; ++j) {
        b[j]=0;
    }
    for ( j = 0; j < n; ++j) {
        if(a[j]!=0)
        {
            b[count++]=a[j];
        }
    }
   // printf("%d\n",count);
    for ( j = 0; j < n; ++j) {
        printf("%d ",b[j]);
    }
    return 0;
}

6.【问题描述】输入一个单向链表,输出该链表中倒数第k个结点,链表的最后一个结点是倒数第1个节点。


【输入形式】输入第一位为K值,其后接一串以空格分隔的整型值。
【输出形式】输出为倒数第K个结点的值,若无,则输出Not Found


【样例输入】3 13 45 54 32 1 4 98 2
【样例输出】4
【样例说明】K值为3,则输出链表倒数第3个结点的值,为4;数据输入间以空格隔开
【评分标准】本题要综合输出正确性及使用的数据结构。需由输入数据构建单链表。不使用链表的将不得分。

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

typedef int ElementType ;
typedef struct LNode
{
    ElementType data;//数据域
    struct LNode *next;//指针域
}LNode,*LinkList;
int length=0;
void list_tail_insert(LinkList *L){
    *L=(LinkList) malloc(sizeof(LNode));
    LNode *s,*r=*L;//r和L一样指向头节点
    ElementType x;
    while (scanf("%d",&x)!=EOF)
    {
        s=(LNode *) malloc(sizeof(LNode));
        s->data=x;
        r->next=s;
        r=s;
        length++;

    }
    r->next=NULL;

}
void Print(LinkList L)
{
    L=L->next;
    while(L)
    {
        printf("%d",L->data);
        L=L->next;//eg 3 4 5,头插 走到3,
        if(L!=NULL){
            printf(" ");
        }
    }
    printf("\n");
}
void find_list_k(LinkList L,int k)
{
    ElementType e;
    LNode *p=L->next,*q=L->next;
    int i=1;
    if(L->next==NULL){
        return ;
    }//判空
    while (i<k&&q->next)
    {
        q=q->next;
        i++;

    }
//没找到
    if(i<k)
    {
        printf("Not Found");
        return ;
    }
    while (q->next){
        q=q->next;
        p=p->next;
    }
    e=p->data;
    printf("%d",e);
}
int main() {
    LinkList L;
    list_tail_insert(&L);
    int post=L->next->data;
    if(length<3)
    {
        printf("Not Found");
        return 0;
    }
    find_list_k(L, post);
    return 0;
}

8.【问题描述】采用头插法和尾插法创建一个单链表。假设链表中的数据元素均为整数。
【输入形式】第一行输入2个整数,第1个为创建方法(1为头插法,2为尾插法),第2个为链表的长度;第2行输入单链表各数据元素。
【输出形式】创建好的单链表,若果为空链表,输出“list is empty!”。

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

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

//头插法
void list_header_insert(LNode **L,int l)//LNode *和LinkList等价
{
*L = (LNode *) malloc(sizeof(LNode));//申请头结点空间
    (*L)->next=NULL;
LNode *s;//申请新的结点
ElementType x;

int j=0;
while (j<l) {
scanf("%d", &x);
s = (LNode *) malloc(sizeof(LNode));
s->data = x;
s->next =(*L)->next;//使x的next指向前驱元素
    (*L)->next =s;//next指向x的地址
j++;
}
}
//尾插法 关键点在于L不移动 r与l地址相同
void list_tail_insert(LNode **L,int l)//LNode *和LinkList等价
{
(*L) = (LNode *) malloc(sizeof(LNode));//申请头节点空间
LNode *s,*r=*L;//申请新的结点,让r的地址与L地址相同,指向同一个地方,同时都指向头节点
ElementType x;
int i=0;

while (i<l) {
scanf("%d", &x);
s = (LNode *) malloc(sizeof(LNode));
s->data=x;
r->next=s;
r=s;
i++;

}
r->next=NULL;
}

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


int main() {
    LinkList L;
    int n,l;
    scanf("%d%d",&n,&l);
    if(n==1)
    {
        list_header_insert(&L,l);//头插法
    } else{
        list_tail_insert(&L,l);//尾插法
    }
    Print(L);

    return 0;
}

13.【问题描述】
输入n(n>1)个正整数,每次将输入的整数插入到链表头部。-1表示输入结束。再输入一个正整数,在链表中查找该数据并删除对应的节点。要求输出进行删除操作后链表中所有节点的值。 
【输入形式】
输入以空格分隔的n个整数,以-1结束输入,再输入一个要删除的整数。

【输出形式】
从链表第一个元素开始,输出链表中所有的节点值。以空格分隔。

【样例输入】
2 4 6 7 8 4 -1

【样例输出】
4 8 7 6 4
【样例说明】
输入以空格分隔的n个整数2 4 6 7 8 4, 以-1结束输入
然后输入2,删除2之后输出剩余整数。

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

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

//头插法
void list_header_insert(LNode **L)//LNode *和LinkList等价
{
*L = (LNode *) malloc(sizeof(LNode));//申请头结点空间
    (*L)->next=NULL;
LNode *s;//申请新的结点
ElementType x;
scanf("%d", &x);
while (x != -1) {
s = (LNode *) malloc(sizeof(LNode));
s->data = x;
s->next =(*L)->next;//使x的next指向前驱元素
    (*L)->next =s;//next指向x的地址
scanf("%d", &x);
}
}

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

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


int main() {
    LinkList L;
    list_header_insert(&L);//头插法
    //Print(L);
    ElementType e;
    scanf("%d",&e);
    int pos=get_elem_seq(L,e);
    if(pos)
    {
        delete_elem(L,pos);
    }
    Print(L);

    return 0;
}

9.【问题描述】编写函数,参数为数组与数组元素个数,使用该函数实现冒泡法排序,输入输出在 main 中完成。

【输入形式】输入5个int型数字

【输出形式】输出按由小到大的排序结果

【样例输入】9 8 4 6 7

【样例输出】4 6 7 8 9


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef int ElemType;
typedef struct {
    ElemType * elem;//存,申请的空间的首地址
    int tab_length;//存储动态数组里元素的个数
}SSTable;
void ST_Init(SSTable *t,int len) {
    (*t).tab_length=len;//元素个数,数组长度
    (*t).elem = (ElemType *) malloc(sizeof(ElemType)*(*t).tab_length);
int i;
for (i = 0; i < (*t).tab_length; i++)
{
scanf("%d",&(*t).elem[i]);
}
}
void Print(SSTable s)
{
    int i;
    for ( i = 0; i <s.tab_length ; ++i) {
        printf("%d ",s.elem[i]);
    }
    printf("\n");
}
void swap(ElemType *a,ElemType *b)
{
int temp=*a;
*a=*b;
*b=temp;
}
void Bobble(SSTable *t)
{
int i,j;
int  flag= 0;
for ( i = 0; i <(*t).tab_length ; i++)//排好了几个
{
for ( j = (*t).tab_length-1; j >i; j--)
{
if((*t).elem[j]<(*t).elem[j-1])
{
swap(&(*t).elem[j],&(*t).elem[j-1]);
flag= 1;//冒泡从后往前先find最小的,如果在j=1时都没有发生交换的都没有找到,说明有序
}
}
if (0==flag)
{
return;//本身有序
}
}
}
int main() {
    SSTable t;
    int len=5;//数组长度
    ST_Init(&t,len);
//    Print(t);
    Bobble(&t);
    Print(t);
    free(t.elem);
    return 0;
}

11.【问题描述】查找顺序表第i个位置(逻辑位序)插入新元素e。若插入位置不合法,则返回false,输出“The insertion position does not exist”和顺序表的表长。成功则输出插入后的新表。假设顺序表的元素为整型数据。

【输入形式】第1行顺序表的长度;第2行顺序表各数据元素;第3行为插入位置和插入元素。

【输出形式】若顺序表插入成功,则先输出插入后的顺序表,插入失败则输出“The insertion position does not exist”和顺序表的表长。

 

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

//静态分配(动态分配的有指针域必须要写名字,静态分配有别名可以不写名字)
typedef struct
{
    int length;
    ElementType data[MaxSize];
}SqList;

int ListInsert(SqList *L,int i,ElementType e)
{
if(i<1||i>(*L).length)
{
return 0;
}
if((*L).length==MaxSize)
{
return 0;
}
int j;
for ( j = (*L).length; j >=i ; j--) {
    (*L).data[j]=(*L).data[j-1];
}
    (*L).data[i-1]=e;
    (*L).length++;
return 1;
}

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

int main() {
    SqList L;//定义一个表
    int ret;
    int n;
    scanf("%d",&n);
    int i;
    for ( i = 0; i < n; ++i) {
        scanf("%d",&L.data[i]);
    }
    ElementType e;//插入的元素的值
    int pos;
    scanf("%d%d",&pos,&e);
    L.length=i;//设置表的长度
    ret= ListInsert(&L,pos,e);
    if(ret)
    {
        PrintList(L);
    } else{
        printf("The insertion position does not exist\n%d",L.length);
    }
    return 0;
}

5.【问题描述】删除一个单链表中第一个值最小的元素:删除一个单链表 L(至少含两个数据结点)中第一个值最小的结点。

【输入形式】第一行输入单链表的长度,第二行单链表的元素。
【输出形式】输出删除前后的单链表,并输出删除的最小值。
【样例输入】

6

1 3 8 4 5 2

【样例输出】

before delete min:1 3 8 4 5 2

after delete min:3 8 4 5 2

min=1

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

typedef int ElementType ;
typedef struct LNode
{
    ElementType data;//数据域
    struct LNode *next;//指针域
    //一个内容包含有数据和next指针
}LNode,*LinkList;
int min;
int len=0;
//尾插法 关键点在于L不移动 r与l地址相同
void list_tail_insert(LNode **L)//LNode *和LinkList等价
{
    *L = (LNode *) malloc(sizeof(LNode));//申请头节点空间
    LNode *s,*r=*L;//申请新的结点,让r的地址与L地址相同,指向同一个地方,同时都指向头节点
    ElementType x;
    int n,i=0;
    scanf("%d", &n);
    scanf("%d", &x);
    min=x;
    while (i<n) {
        if(min>x)
        {
            min=x;
        }
        len++;
        s = (LNode *) malloc(sizeof(LNode));
        s->data=x;
        r->next=s;
        r=s;
        scanf("%d", &x);
        i++;
    }
    r->next=NULL;
}
//按位查找 链表是不能实现随机存取的,只能遍历查找 链表的下标从1开始
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;
    L=L->next;
    while (L)
    {
        if(L->data==search_val){
            return i;
        }
        L=L->next;
        i++;
    }
    return 0;
}

//删除第i个位置
int delete_elem(LinkList *L,int i)//加不加引用取决与于L(首地址)会不会改变 比如头插法尾插法是为L分配空间的,形成头结点
{
    LinkList  p=get_elem_val(*L,i-1);//获取i-1的地址
    if(NULL==p)
    {
        return 0;
    }
    LinkList q=get_elem_val(*L,i);;
    //printf("%s\n ",p->data);//可以看出,当i=1时,i-1表示的是L结点,也就是头结点,头节点的值是NULL,也就是对应的%d输出时会输出0
//printf("%d\n ",p->data);
    p->next=q->next;
    free(q);
    return 1;
}
void Print(LinkList L)
{
    L=L->next;//L是指向头节点的,头结点里面是没有值的,所以需要从下一个结点,也就是a1开始
    while(L)
    {
        printf("%d ",L->data);
        L=L->next;
    }

}


int main() {
    LinkList L;
    list_tail_insert(&L);//尾插法
    printf("before delete min:");
    Print(L);
    int pos= get_elem_seq(L,min)+1;
    delete_elem(&L,pos);
    printf("\nafter delete min:");
    Print(L);
    printf("\nmin=%d",min);
    free(L);
    return 0;
}

 


2.问题描述】对一含有n个整数的数组,使用堆排序将其由小到大排序。
【输入形式】第一行为元素个数n,第二行为n个整数(以空格隔开)。
【输出形式】输出n个整数(以空格隔开)
【样例输入】

43 2 56 1 22 9
【样例输出】
1 2 9 22 43 56
【样例说明】

#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct {
    ElemType * elem;//存,申请的空间的首地址
    int tab_length;//存储动态数组里元素的个数
}SSTable;
void ST_Init(SSTable *t,int len) {
    (*t).tab_length=len;//元素个数,数组长度
    (*t).elem = (ElemType *) malloc(sizeof(ElemType)*(*t).tab_length);
    int i;
    for (i = 0; i < (*t).tab_length; i++)
    {
        scanf("%d",&(*t).elem[i]);
    }
}
void Print(SSTable s)
{
    int i;
    for ( i = 0; i <s.tab_length ; ++i) {
        printf("%d ",s.elem[i]);
    }
    printf("\n");
}
void swap(ElemType *a,ElemType *b)
{
int temp=*a;
*a=*b;
*b=temp;
}
void big_heap(SSTable *s,int i,int len)
{
int father=i,son;
son=2*i+1;//左孩子
while (son<len)
{
if(son+1<len&&(*s).elem[son]<(*s).elem[son+1])
{
son++;//拿到孩子中最大的
}
if((*s).elem[son]>(*s).elem[father])
{
swap(&((*s).elem[son]),&((*s).elem[father]));
father=son;
son=father*2+1;
} else{
break;
}
}
}
void heap_sort(SSTable *s)
{
int len=(*s).tab_length;
int i=(*s).tab_length/2-1;//最后一根子树的父结点
for ( ; i >=0 ; i--) {
big_heap(s,i,len);//最好 O(1),最差O(logn)
}
swap(&((*s).elem[(*s).tab_length-1]),&((*s).elem[0]));
for ( i = (*s).tab_length-1; i >1 ; i--) {
big_heap(s,0,i);//都是O(logn)
swap(&((*s).elem[i-1]),&((*s).elem[0]));
}
}

int main() {
    SSTable t1;
    int n;
    scanf("%d",&n);
    ST_Init(&t1,n);
//    Print(t1);
    heap_sort(&t1);
    Print(t1);
    return 0;
}


 

7.【问题描述】设有一个顺序表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 1000
typedef int ElementType;

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

void spilt_list(SqList *L,SqList *L1)
{
SqList L2;
int i;
for ( i = 0; i <(*L).length ; ++i) {
L2.data[i]=(*L).data[i];
}
L2.length=(*L).length;
int len=L2.length;
int k,j;
for ( i = 0,k=0,j=0; i <len; i++) {
if(L2.data[i]%2==0)//偶数
{
    (*L1).data[k++]=(*L).data[i];
} else{
    (*L).data[j++]=(*L).data[i];
}
}
    (*L1).length=k;
    (*L).length=j;
}
void PrintList(SqList L)
{
    int i;
    for ( i = 0; i < L.length; i++) {
        printf("%d ",L.data[i]);
    }

}

int main() {
    SqList L,L1;
    L1.length=0;
    int i=0,j;
    while (scanf("%d",&L.data[i])!=EOF)
    {
        i++;
    }
    L.length=i;
    printf("测试结果:\n原始数据:");
    for ( j = 0; j <i ; ++j) {
        printf("%d  ",L.data[j]);
    }
    printf("\n初始顺序表L:  ");PrintList(L);
    printf("\n拆分后:\n奇数顺序表L:  ");
    spilt_list(&L,&L1);
    PrintList(L);
    printf("\n偶数顺序表L1: ");
    PrintList(L1);
    return 0;
}


 

问题描述】令L=(x1,x2…,xn),L2=(y1,y2,…,ym)是两个线性表,n≥1,m≥1,采用带头结点的单链表存储,设计一个算法合并L1、L2,结果放在线性表L3中。L3仍采用单链表存储。要求不破坏原有的单链表L1和L2。

    L3=(x1, y1, x2,y2,…,xm,ym,xm+1,…,xn)m<=n

    L3=(x1, y1, x2,y2,…,xn,yn,yn+1,…,ym)m>=n

【输入形式】任意输入2行整数(分别为L1和L2的原始数据)

【输出形式】合并前的单链表L1、L2及合并后L1、L2和L3。

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

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

void list_tail_insert(LinkList *L)//LNode *和LinkList等价
{
*L = (LNode *) malloc(sizeof(LNode));//申请头节点空间
LNode *s, *r = *L;//申请新的结点,让r的地址与L地址相同,指向同一个地方,同时都指向头节点
ElementType x;
scanf("%d", &x);char c;
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;

}

void Merge1(LinkList  L1,LinkList  L2,LinkList *L3){
LinkList p =L1->next,q = L2->next,s,r; //新节点和尾指针
*L3 = (LinkList )malloc(sizeof(LNode));//L3头结点
r = *L3;
while(p!=NULL && q!=NULL){
s = (LinkList )malloc(sizeof(LNode ));
s->data = p->data;
r->next = s;
r=s;
p = p->next;
//另一一个链表
s = (LinkList )malloc(sizeof(LNode ));
s->data = q->data;
r->next = s;
r=s;
q = q->next;
}
if(q!=NULL)  p = q;
while(p!=NULL){
s = (LinkList )malloc(sizeof(LNode ));
s->data = p->data;
r->next = s;
r=s;
p = p->next;
}
r->next = NULL;

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

}
int main()
{
    LinkList L1,L2,L3;
    list_tail_insert(&L1);
    list_tail_insert(&L2);
    printf("L1: "); Print(L1);
    printf("\nL2: "); Print(L2);
    Merge1(L1,L2,&L3);

    printf("\nL1和L2合并后:\nL1: "); Print(L1);
    printf("\nL2: "); Print(L2);
    printf("\nL3: ");
    Print(L3);
    return 0;
}

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值