C(练习)

一、已有a,b两个链表,每个链表中的结点包括学号和成绩。要求把两个链表合并,并按学号升序排列

#include <stdio.h>
#include<malloc.h> 
//合并两个链表 
#define LEN sizeof(struct student)
struct student{
	long num; //序号 
	int score; //分数 
	struct student *next;
};
struct student lista,listb;
int n,sum=0;
int main()
{
	struct student *creat(void);  //函数声明
	struct student *insert(struct student *,struct student *);
	void print(struct student *);
	struct student * ahead,* bhead,* abh; 
	
    printf("input list a:\n");
    ahead=creat();  //调用creat函数建立表A,返回头地址 
    sum+=n;
    
    printf("input list b:\n");
    bhead=creat();   // 调用creat函数建立表B,返回头地址
    sum+=n;
    
    abh=insert(ahead,bhead); //调用insert函数,将两表合并 
    print(abh);					//输出合并后的链表 
    return 0;
}
//create list
struct student *creat(void){
	struct student *p1,*p2,*head;
	n=0;
	p1=p2=(struct student*)malloc(LEN);
	printf("input number & scores of student:\n");
	printf("if number is 0,stop inputing. \n");
	scanf("%ld,%d",&p1->num,&p1->score);
	head=NULL;
	while(p1->num!=0){
		n=n+1;
		if(n==1)
			head=p1;
		else
			p2->next=p1;
		p2=p1;
		p1=(struct student *)malloc(LEN);
		scanf("%ld,%d",&p1->num,&p1->score);
	}
	p2->next=NULL;
	return (head);
}
//insert,the function is merge
struct student *insert(struct student *ah,struct student *bh)
	{
		struct student *pa1,*pa2,*pb1,*pb2;
		pa2=pa1=ah;
		pb2=pb1=bh;
		do{
			while((pb1->num>pa1->num) &&(pa1->next!=NULL))
			{	pa2=pa1;
				pa1=pa1->next;
			}
		if(pb1->num<=pa1->num)
		{
			if(ah==pa1)
				ah=pb1;
			else
				pa2->next=pb1;
			pb1=pb1->next;
			pb2->next=pa1;
			pa2=pb2;
			pb2=pb1;
		}
	}while((pa1->next!=NULL)||(pa1==NULL && pb1!=NULL));
	if((pb1!=NULL)&&(pb1->num>pa1->num) &&(pa1->next==NULL))
	pa1->next=pb1;
	return (ah);
}

//print
void print(struct student *head){
	struct student *p;
	printf("these are %d records:\n",sum);
	p=head;
	if(p!=NULL)
	do{
		printf("%ld %d\n",p->num,p->score);
		p=p->next;
	}while(p!=NULL);
}

二、将两个顺序表合并为一个新的有序顺序表,并由函数返回结果顺序表

思路:按顺序不断取下两个顺序表表头较小的结点存入新的顺序表中。然后,看哪个表还有剩余,将剩下的部分加到新的顺序表后面

bool Merge(SeqList A,SeqList B,SeqList C){
    if(A.length+B.lenght>C.length)
    return false;
    int i=0,i=0,k=0;
    while(i<A.length && j<B.length){
        if(A.data[i]<B.data[j])
            C.data[k]=A.data[i];
        else
            C.data[i]=B.data[j];
}
    while(i<A.length)
        C.data[k++]=A.data[i++];
    C.length=k;
    return false;
}

三、给定一个含n(n>=1)个整数的数组,请设计一个在时间上尽可能高效的算法,找出数组中未出现的最小正整数。例如,数组{-5,3,2,3}中未出现的最小正整数是1;数组{1,2,3}中未出现的最小正整数是4.要求:

(1)给出算法的基本设计思想

采用空间换时间。

分配一个用于标记数组B【n】,用来记录A中是否出现了1~n个正整数,B【0】对应正整数1,B【n-1】对应正整数n,

初始化B中全部为0。由于A中含有n个整数,因此可能返回的值是1~n+1,当A中n个数恰好为1~n时返回n+1。

当数组A中出现了小于等于0或大于n的值时,会导致1~n中出现空余位置,返回结果必然在1~n中,因此对于A中出现了小于等于0或大于n的值不采取任何操作。

       算法流程:从A【0】开始遍历A,若0<A[i]<=n,则令B[A[i-1]]=1;否则不做操作。对A遍历后,开始遍历数组B,若能查找到第一个满足B【i】==0的下标i,返回i+1即为结果。此时说明A中未出现的最小正整数在1~n之间。

若B【i】全部不为0,返回i+1(跳出循环时i=n,i+1=n+1)此时说明A中未出现的最小正整数时n+1

(2)根据设计思想,采用C/C++描述,并给出注释

int findMissMin(int A[],int n){
    int i,*B;        //标记数组
    B=(iny *)malloc(sizeof(int )*n); //分配空间
    mesmset(B,0,sizeof(int *)n);  //赋初值为0
    for(i=0;i<n;i++)
        if(A[i]>0&&A[i]<=n)   //若A【i】的值介于1~n,则标记数组B
            B[A[i]-1]=1;
    for(i=0;i<n;i++)   //扫描数组B,找到目标值
        if(B[i]==0) break;

    return i+1;    //返回结果
}

(3)说明你所设计算法的时间复杂度和空间复杂度

遍历A一次,遍历B一次,两次循环内操作位O(1),会因此时间复杂度位O(n).空间复杂度:额外分配了B【n】,空间复杂度位O(n)

四、两个整数A=a1,a2,a3...an,B=b1,b2,b3....bn序列存入两个单链表中,设计一个算法,判断序列B是否为序列A的连续子序列

思路:因为两个整数序列已经存入两个链表中,操作从两个链表的第一个结点开始,若对应数据相等,则指针后移;若对应数据不等,则从A链表上次开始比较结点的后继开始,B链表仍从第一个结点开始,直到B链表到尾表示匹配成功。

A链表到尾而B链表未到尾表示失败。

操作中应当记住A链表每次开始的结点,以便下次匹配时从其后继开始

int Pattern(LinkList A,LinkList B){
    LNode *p=A;  //p为A链表的工作指针,本题假定A和B均无头结点
    LNode *pre=p;  //pre记住每趟比较中A链表的开始结点
    LNode *q=B;    //q是B链表的工作指针
    while( P&&q)
        if(p->data==q->data){//结点值相等
        p=p->next;
        q=q->next;
        }
        else{
            pre=pre->next;
            p=pre;  //A链表新的开始比较结点
            p=B;
    }
    if(q==NULL)
        return 1;  //B是A的子序列
    else
        return 0;  //B不是A的子序列

}

五、设计算法判断带头结点的循环双链表是否对称

思路:让p从左向右扫描,q从右向左扫描,直到他们

指向同一个结点(p==q,当循环双链表结点个数为奇数时)

相邻(p->next=q或q->prior=p,当循环双链表中结点个数为偶数时)

为止,若他们所指结点值相等,则继续进行下去,否则返回0;若比较全部相等,则返回1

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值