数据结构与算法-头歌【2】链式线性表--课上练

 本意是整理和复习,理解不深或者有错误的评论区提出即可。

只有第一关的代码里面有结构体的定义,其余我只放了功能函数。

初始代码

#include <stdio.h>
#include <stdlib.h>
//第一关代码

struct node
{//此处填写代码,定义链表结点类型,包含一个存放整型数据的 data 成员,和一个指向下一个结点的next成员
    
    
};

struct node *mycreateList()
{//此处填写代码,创建一个只有一个头结点的空链表,头节点的数据域赋值为0,并将表头结点的地址返回
  

}


//第二关代码

void myinsertHead(struct node * head, int insData )
{
	/*在此处完成任务,实现在head为表头d 链表的头插数据元素insData的功能*/
	//begin
   
	
	//end 
}

void myinsertTail(struct node *  head , int insData )
{
	/*在此处完成任务,在head为表头的单链表表尾插入数据元素insData*/
	//begin
   
	
	//end 	
}

void myprintList(struct node *L)
{
     /*在此处完成任务,输出head为表头链表中的数据,每输出一个数据换一行*/
	//begin
	
	
	//end 
    
}

//第三关代码
 void reverseList_link( struct node *L)
 {
    //请在此处填入代码,实现链表逆置功能 
 	//begin
 	
 	 
	//end 
 }


//第四关代码
int locateAndChange( struct node *L, int data)
 {
    //请在此处填入代码,在头结点为L的链表中查找 与data值相等的第一个结点,若能找到该结点,则将该结点的值与前驱结点的值交换
    //若未找到与data值相等的结点,则返回值为-1,若找到的结点无前驱结点,则返回值为0,否则返回值为前驱结点的值
 	//begin
 	
 	 
	//end 
 }

//第五关代码
int destroyList(struct node *L)
{
  //请在此处填写代码,实现将链表L的结点空间回收
 //返回值为回收结点的个数,含头结点在内   

}

第1关:链表数据结构定义及初始化链表

题目

任务描述

本关任务:完成创建一个带表头的空链表的操作。

编程要求

根据提示,在右侧编辑器补充代码,完成链表结点定义,创建带表头的空链表并返回表头的函数。


开始你的任务吧,祝你成功!

测试

输出:success to create 0 

代码

功能函数

#include <stdio.h>
#include <stdlib.h>
//第一关代码

struct node
{//此处填写代码,定义链表结点类型,包含一个存放整型数据的 data 成员,和一个指向下一个结点的next成员
    int data;
    struct node* next;
};

struct node *mycreateList()
{//此处填写代码,创建一个只有一个头结点的空链表,头节点的数据域赋值为0,并将表头结点的地址返回
    struct node* list = (struct node*)malloc(sizeof(struct node));
    list->next = NULL;
    list->data = 0;

    return list;
}

主函数

int main(void)
{
   struct node *L = mycreateList();
   if(L==NULL)
       printf("fail to create");
   else
       { printf("success to create");
         printf(" %d ",L->data); 
       }
    return 1;   
}

突然发现老师的代码给错了,这个是文件里面的第二关的代码,但是应该是第一关地方的哈哈 

第2关:链表插入和遍历链表输出链表的操作

题目

任务描述

本关任务: 1.编写一个能向表尾插入结点的函数; 2.编写一个能在表头插入结点的函数; 3.编写一个能遍历链表并输出链表各结点数据元素的函数;

相关知识

本关使用的链表结点结构定义为:

 
  1. struct node
  2. {
  3. int data ; //存放结点的数据元素
  4. struct node *next ; //指向下一个结点的指针,尾结点该域值为NULL
  5. };

开始你的任务吧,祝你成功!

测试

输出:

5

3

1

2

4

6

代码

功能函数

//第二关代码

void myinsertHead(struct node * head, int insData )
{
	/*在此处完成任务,实现在head为表头的链表的头插数据元素insData的功能*/
	//begin
    struct node* list = (struct node*)malloc(sizeof(struct node));
    list->next = NULL;//存放新结点

    list->data = insData;

    list->next = head->next;
    head->next = list;
	//end 
}

void myinsertTail(struct node *  head , int insData )
{
	/*在此处完成任务,在head为表头的单链表表尾插入数据元素insData*/
	//begin
    struct node* list = (struct node*)malloc(sizeof(struct node));
    list->next = NULL;//存放新结点
    struct node* p = (struct node*)malloc(sizeof(struct node));
    p->next = NULL;//指向链表当前结点
    p = head;
    list->data = insData;//给指针赋值

    while(p->next){//找到尾部结点
        p = p->next;
    }
    p->next = list;
	//end 	
}

void myprintList(struct node *L)
{
     /*在此处完成任务,输出head为表头链表中的数据,每输出一个数据换一行*/
	//begin
	struct node* p = L->next;
    while(p){
        printf("%d\n", p->data);
        p = p->next;
    }
	//end 
    
}

主函数

int main(void)
{
	struct node *L = mycreateList();
    int a[]={1,2,3,4,5,6};
    for(int i=0;i<6;i++)
        if(i%2) myinsertTail(L,a[i]);
        else  myinsertHead(L,a[i]);
	myprintList(L);
 } 

第3关:链表逆置

题目

任务描述

本关任务:完成算法,能实现将链表中的数据元素逆置。

问题描述:有一链表里面存放的是某公司销售人员的月销售数量,目前链表中存放的销售数量是按从小到大排序的,请编写一个算法,将销售数量从大到小排序。 结点类型定义如下:

  1. typedef struct node
  2. {
  3. int saleAmount ;//销售数量
  4. struct node *next;//指向下一产品的指针
  5. }NODE ;
  6. typedef struct node *pNode ;

开始你的任务吧,祝你成功!

测试

输入:5 4 12 51 82 132

输出:132 82 51 12 4

输入:6 5 11 151 192 212 500

输出:500 212 192 151 11 5

代码

功能函数

//第三关代码
 void reverseList_link(struct node *L)
 {
    //请在此处填入代码,实现链表逆置功能 
 	//begin
 	 struct node* list =(struct node*)malloc(sizeof(struct node));
     list->next = NULL;//指向头结点
 	 struct node* p =(struct node*)malloc(sizeof(struct node));
     p->next = NULL;//指向当前链表结点
     struct node* tList =(struct node*)malloc(sizeof(struct node));
     tList->next = NULL;//暂时的链表结点

 	 list = L;
 	 p = L->next;
     L->next = NULL;//头结点置空

     while(p){
         tList = p;
         p = p->next;//先把指向当前链表的指针指向下一个元素(关键)
         //头结点插入元素
         tList->next = L->next;
         L->next = tList;
     }
	//end 
 }

主函数

int main(void)
 {
 	 struct node  *pllist = mycreateList() ;
 	 int num ;
	 int data;
 	 scanf("%d",&num);
 	 for(int i = 0;i < num; i++)
 	   {
 	   	  scanf("%d",&data);
 	   	  myinsertTail(pllist, data);
		}
	reverseList_link(pllist);
	myprintList(pllist);	
 }

 第4关:查找和交换

题目

任务描述

本关任务:查找符合条件的结点,并将该结点的值与前驱结点的值交换。


开始你的任务吧,祝你成功!

测试

输入:5 -12 34 23 6 7 34

输出:-12 

代码

功能函数

//第四关代码
int locateAndChange( struct node *L, int data)
 {
    //请在此处填入代码,在头结点为L的链表中查找 与data值相等的第一个结点,若能找到该结点,则将该结点的值与前驱结点的值交换
    //若未找到与data值相等的结点,则返回值为-1,若找到的结点无前驱结点,则返回值为0,否则返回值为前驱结点的值
 	//begin
 	struct node* p =(struct node*)malloc(sizeof(struct node));
    p->next = NULL;//指向当前链表结点
    p = L;

    //情况一:与data相等的结点的前驱节点是头结点
    if(p->next->data == data){
        return 0;
    }
    //情况二:找到该节点,与其前驱节点的值交换,输出前驱节点的值
    struct node* list =(struct node*)malloc(sizeof(struct node));
    list->next = NULL;//存放当前判断的结点
    struct node* t =(struct node*)malloc(sizeof(struct node));
    t->next = NULL;//存放当前判断的前驱结点
            
    p = p->next;
    while(p->next){
        if(p->next->data == data){
            int temp;
            list = p->next;
            t = p;
            //交换两个结点的值
            temp = t->data;
            t->data = list->data;
            list->data = temp;
            return list->data;      //输出交换后的当前结点的值(前驱节点的值)
        }
        p = p->next;
    }
    return -1;

	//end 
 }

主函数

int main(void)
 {
 	 struct node  *pllist = mycreateList() ;
 	 int num ;
	 int data;
     int pos ;
 	 scanf("%d",&num);
 	 for(int i = 0;i < num; i++)
 	   {
 	   	  scanf("%d",&data);
 	   	  myinsertTail(pllist, data);
		}
    scanf("%d",&data); 
	printf("%d",locateAndChange(pllist,data));
 }

第5关:链表销毁

题目

任务描述

链表的结点所占空间是动态分配的堆空间,程序员应在退出程序时释放动态分配的空间。

本关任务: 完成destroyLinklist函数,实现链表结点空间的回收


开始你的任务吧,祝你成功!

测试

输入:5 1 2 3 4 5

输出:6

输入:1 1

输出:2

代码

功能函数

//第五关代码
int destroyList(struct node *L)
{
  //请在此处填写代码,实现将链表L的结点空间回收
 //返回值为回收结点的个数,含头结点在内   
    struct node* p =(struct node*)malloc(sizeof(struct node));
    p->next = NULL;//循环
    struct node* list =(struct node*)malloc(sizeof(struct node));
    list->next = NULL;//暂存
    int n = 1;//个数

    p = L->next;
    while(p){
        list = p;
        free(list);
        p = p->next;
        n++;
    }
    free(L);
    return n;
}

主函数

int main(void)
 {
 	 struct node  *pllist = mycreateList() ;
 	 int num ;
	 int data;
     int pos ;
 	 scanf("%d",&num);
 	 for(int i = 0;i < num; i++)
 	   {
 	   	  scanf("%d",&data);
 	   	  myinsertHead(pllist, data);
		}
   
	printf("%d",destroyList(pllist));
 }
 

  • 5
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

倒霉蛋要写检讨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值