任务三 链表

1.创建链表

(1)【基本要求】
从键盘输入一组整数,创建单向链表,并输出链表中的数据。
样例输入:2 5 7 6 3 4
样例输出:2 5 7 6 3 4
(2)【功能实现】

#include<stdio.h>
#include<stdlib.h>
#define N 4 /*链表的长度*/ 
struct Node //链表结点的结构体 
{ 
	int data; //结点的值
	struct Node *next; //指向下一个结点的指针 
}; 
//创建n个结点的链表,返回链表的首结点地址 
Node* createList(int n); 
//输出头结点地址为first的链表 
void printList(Node *first); 
//释放头结点地址为first的链表所有结点占据的内存空间 
void destoryList(Node *first);
int main() 
{ 
	Node *list; 
	printf("请输入%d个数以建立链表\n",N); 
	//创建N个结点的链表,链表首结点地址=>list 
	list=createList(N); 
	printList(list); //输出头结点地址为list链表
	destoryList(list); //释放头结点地址为list的链表所有结点占据的内存空间 
	printf("\n"); 
} 
//创建n个结点的链表,返回链表的首结点地址 
Node* createList(int n) 
{ /*尾插法建立链表*/
  //first:指向首结点,last:指向最后一个结点,t指向临时结点
    Node *t,*first,*last; 
    int i; 
  //分配一个结点的空间 => 第1个结点 
    first=(Node *)malloc(sizeof(Node)); 
    scanf("%d",&first->data); //输入第一个结点的值 
    last=first; //只有一个结点,既是队首也是队尾 
   //创建其余的n-1个结点 
	for(i=n-1;i>0;i--) 
	{ 
	//分配一个结点的空间 => 临时结点t 
    	t=(Node *)malloc(sizeof(Node)); 
    	scanf("%d",&t->data); //输入下一个结点的值
		last->next=t; //将临时结点t插入到链表的尾部
		last=t; //临时结点t变成链表的尾部
	} 
		last->next=NULL; //队尾结点的下一个结点为空 
		return first; 
} 
/*遍历链表并输出*/
void printList(Node *first) 
{ 
	Node *p=first;
	while(p!=NULL) 
	{ 
		printf("%3d",p->data); 
		p=p->next; 
	} 
	printf("\n"); 
} 
//释放头结点地址为first的链表所有结点占据的内存空间 
//free(p)释放指针p指向的结点占据的内存空间
//free函数,在stdlib.h头文件中定义 
void destoryList(Node *first) 
{ 
	Node *p=first,*temp;
  	while(p!=NULL) 
	{ 
//使用过多少次malloc函数分配内存,就要使用多少次free函数释放内存 
    	temp=p->next; //暂存下一个结点的地址 
    	free(p); //释放当前结点的内存空间 
    	p=temp; // p指向下一个结点 
	} 
} 

(3)【运行结果】

在这里插入图片描述

2.链表合并

(1)【基本要求】
从键盘输入两组由小到大的整数,每组数据创建一个链表。然后将两个链表合并,合并后的链表仍然保持由小到大的顺序。最后输出合并后的链表。
样例输入:
1 2 5 7
2 3 6 8 9
样例输出:1 2 2 3 5 6 7 8 9
(2)【功能实现】
代码一:

#include<stdio.h> 
#include<stdlib.h> 
#define N1 4 //链表La的长度 
#define N2 5 //链表Lb的长度 
struct Node{ 
	int data; 
	struct Node *next;  
}; 
Node* createList(int n);   
Node* mergeList(Node *la,Node *lb);//两个有序链表合并,返回合并后链表的首结点地址 
void printList(Node *p);  
void destoryList(Node *first);
int main(){ 
	Node *la,*lb; 
	printf("请按照升序,输入%d个数以建立链表La\n",N1);
	//创建N1个结点的链表,链表首结点地址=>la 
	la=createList(N1); 
	printf("请按照升序,输入%d个数以建立链表Lb\n",N2);
	//创建N2个结点的链表,链表首结点地址=>lb 
	lb=createList(N2); 	
	la=mergeList(la,lb);//合并两链表=>la 
	printList(la);//输出链表la 
	destoryList(la);//释放合并后的链表所有结点占据的内存空间 
	printf("\n");  
} 
Node* createList(int n){ 
    Node *t,*first,*last; 
    int i;  
    first=(Node *)malloc(sizeof(Node));    
	scanf("%d",&first->data); 
    last=first;    
    for(i=n-1;i>0;i--) 
    { 
        t=(Node *)malloc(sizeof(Node));         
		scanf("%d",&t->data); 
        last->next=t; 
        last=t; 
    } 
 last->next=NULL; 
    return first; 
} 
Node* mergeList(Node *la,Node *lb){   
    Node *first=NULL;  
    Node *last=NULL;   
    while(la&&lb) {
	        if(la->data<lb->data) 
         {   
	        if(first==NULL)  
	        {     
			first=la;
		        last=la;
	        }
	        else 
	        {     
		      last->next=la;
              last=la;
               }               
			la=la->next;  
	}
        else if (la->data>lb->data) 
        {          
	     if(first==NULL)
	       {    
            first=lb;
	            last=lb;
	       }
	       else 
	       {     
		     last->next=lb;
	             last=lb;
	       }             
		   lb=lb->next; 
        } 
        else 
        {     
	       if(first==NULL)
	       {      
		      first=la;
		      last=la;
	       } 
    	      else      {             
			last->next=la; 
  	        last=la;
	       }
   	       la=la->next;    
			last->next=lb; 
            last=lb;             
			lb=lb->next; 
        } 
    } 
    if(la)  // la≠0
	    last->next=la;
    if(lb)  // lb≠0
		last->next=lb;
    return first; 
} 
void printList(Node *first) 
{ 
     Node *p=first;
     while(p!=NULL){          
	 printf("%3d",p->data); 
        p=p->next; 
     } 
     printf("\n"); 
} 
void destoryList(Node *first) 
{ 
    Node *p=first,*temp;
    while(p!=NULL){                       
	 temp=p->next;  
   	   free(p); 
   	   p=temp; 
   } 
} 

代码二:

#include<stdio.h> 
#include<stdlib.h> 
#define N1 4 /*链表La的长度*/  
#define N2 5 /*链表Lb的长度*/ 
struct Node  //链表的结点 
{ 
	int data; 				
	struct Node *next; 
};  
Node* createList(int n); 
/*将结点t连接到last指向的结点后面 
  在函数中,由于first、last的值可能被修改, 还需要带回到调用的函数,
                  所以实参是fisrt、last的地址 
  firstPoint=&first 
  lastPoint=&last */
void append(Node **firstPoint,Node **lastPoint,Node *t);  
//两个有序链表合并,返回合并后链表的首结点地址 
Node* mergeList(Node *la,Node *lb); 
//打印链表 
void printList(Node *p); 
//释放头结点地址为first的链表所有结点占据的内存空间 
void destoryList(Node *first);
int main() 
{ 
	Node *la,*lb; 
	printf("请按照升序,输入%d个数以建立链表La\n",N1); 
	//创建N1个结点的链表,链表首结点地址=>la 
	la=createList(N1); 
	printf("请按照升序,输入%d个数以建立链表Lb\n",N2); 
	//创建N2个结点的链表,链表首结点地址=>lb 
	lb=createList(N2); 
	la=mergeList(la,lb); //合并两链表=>la 
	printList(la); //输出链表la 
	destoryList(la); //释放合并后的链表所有结点占据的内存空间 
	printf("\n");  
} 

//创建n个结点的链表,返回链表的首结点地址   
Node* createList(int n) 
{ /*尾插法建立链表*/
    Node *t,*first,*last; 
    int i; 
    //分配一个结点的空间 => 第1个结点 
    first=(Node *)malloc(sizeof(Node)); 
    scanf("%d",&first->data); //输入第一个结点的值 
    last=first; //只有一个结点,既是链表的首部也是链表的尾部   
    //创建其余的n-1个结点 
    for(i=n-1;i>0;i--) 
    { 
	//分配一个结点的空间 => 临时结点t 
        t=(Node *)malloc(sizeof(Node)); 
        scanf("%d",&t->data); //输入下一个结点的值
        last->next=t;  //将临时结点t插入到链表的尾部
        last=t; //临时结点t变成链表的尾部
    } 
    last->next=NULL; //链表的尾部结点的下一个结点为空 
    return first; 
}

 //将结点t接到首结点地址为*firstPoint,尾结点地址为 *lastPoint 的链表的尾部
void append(Node **firstPoint,Node **lastPoint,Node *t)
{
	if(*firstPoint==NULL) //合并后的链表为空 
	        //结点t既作为合并后的头结点 
		*firstPoint=t;
	else //合并后的链表不为空
	        //将结点t插入到合并后链表的尾部 
		(*lastPoint)->next=t;
        *lastPoint=t;//t变成并后链表的最后一个结点 
} 

//两个链表合并,返回合并后链表的首结点地址 
Node* mergeList(Node *la,Node *lb)  
{   /*将两个链表按递增序列排序*/
    Node *first=NULL; //合并后链表的首结点地址 
    Node *last=NULL;  //合并后链表的尾结点地址
    //链表la和链表lb都不为空(都没有到最后)  
    while(la&&lb) 
    { 
    	 //链表la当前结点的值<链表lb当前结点的值
        if(la->data<lb->data) 
        {
        	//将la的第1个结点,连到last的后面 
         	append(&first,&last,la);
                la=la->next; //链表la指针移向下一个结点 
	}
        else if (la->data>lb->data) //链表la当前结点的值>链表lb当前结点的值
	{
        	//将lb的第1个结点,连到last的后面 
		append(&first,&last,lb);
           	lb=lb->next; //链表lb指针移向下一个结点
        } 
        else //链表la当前结点的值=链表lb当前结点的值

        {  

        	//将la的第1个结点,连到last的后面 
		append(&first,&last,la);
   	       	la=la->next; //链表la指针移向下一个结点
   	       //将lb的第1个结点,连到last的后面  
		append(&first,&last,lb);
           	lb=lb->next; //链表lb指针移向下一个结点
        } 
    } 
    //链表la不为空,链表lb为空 
    if(la)  // la≠0
	    last->next=la;
   //链表lb不为空,链表la为空 
    if(lb)  // lb≠0
		last->next=lb;
    return first; 
} 

/*遍历链表并输出*/
void printList(Node *first) 
{ 
   Node *p=first;
   while(p!=NULL) 
   { 
       printf("%3d",p->data); 
       p=p->next; 
   } 
   printf("\n"); 
} 

//释放头结点地址为first的链表所有结点占据的内存空间 
//free(p)释放指针p指向的结点占据的内存空间
//free函数,在stdlib.h头文件中定义 
void destoryList(Node *first) 
{ 
   Node *p=first,*temp;
   while(p!=NULL) 
   { 
           //使用过多少次malloc函数分配内存,就要使用多少次free函数释放内存 
           temp=p->next; //暂存下一个结点的地址 
   	   free(p); //释放当前结点的内存空间 
   	   p=temp;  // p指向下一个结点 
   }  
}

(3)【运行结果】
在这里插入图片描述

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值