【数据结构】第2章线性表(头歌习题)【合集】

文章目录

  • 第1关:实现顺序表各种基本运算的算法
    • 任务描述
    • 编程要求
    • 完整代码
  • 第2关:实现单链表各种基本运算的算法
    • 任务描述
    • 编程要求
    • 完整代码
  • 第3关:移除顺序表中所有值等于x的元素
    • 任务描述
    • 编程要求
    • 完整代码
  • 第4关:逆置顺序表
    • 任务描述
    • 编程要求
    • 完整代码
  • 第5关:删除有序顺序表中的重复项
    • 任务描述
    • 编程要求
    • 完整代码
  • 第6关:拆分单链表
    • 任务描述
    • 相关知识
    • 编程要求
    • 完整代码
  • 第7关:删除单链表中值最大的结点
    • 任务描述
    • 编程要求
    • 测试说明
    • 完整代码
  • 第8关:单链表插入排序
    • 任务描述
    • 相关知识
    • 编程要求
    • 测试说明
    • 完整代码
  • 第9关:逆置单链表
    • 任务描述
    • 编程要求
    • 测试说明
    • 完整代码
  • 第10关:移除链表元素
    • 任务描述
    • 编程要求
    • 测试说明
    • 完整代码
  • 第11关:约瑟夫环
    • 任务描述
    • 编程要求
    • 测试说明
    • 完整代码
  • 第12关:链表的中间结点
    • 任务描述
    • 编程要求
    • 测试说明
    • 完整代码
  • 第13关:回文链表
    • 编程要求
    • 测试说明
    • 完整代码
  • 第14关:中位数
    • 任务描述
    • 编程要求
    • 测试说明
    • 完整代码
  • 第15关:合并两个有序链表
    • 任务描述
    • 编程要求
    • 测试说明
    • 提示:
    • 完整代码

第1关:实现顺序表各种基本运算的算法

任务描述

本关任务:实现顺序表各种基本运算的算法。

目的: 领会顺序表存储结构和掌握顺序表中各种基本运算算法设计。
内容: 编写程序,实现顺序表的各种基本运算和整体建表算法(假设顺序表的元素类型ElemType 为char),并在此基础上设计一个主程序,完成如下功能:
(1)初始化顺序表L。
(2)依次插入a、b、c、d、e元素。
(3)输出顺序表L。
(4)输出顺序表L长度。
(5)判断顺序表L是否为空。
(6)输出顺序表L的第3个元素。
(7)输出元素a的位置。
(8)在第4个元素位置上插入f元素。
(9)输出顺序表L。
(10)删除顺序表L的第3个元素。
(11)输出顺序表L。
(12)释放顺序表L。

编程要求

根据提示,在右侧编辑器补充代码,完成线性表基本运算算法实现。

测试说明
平台会对你编写的代码进行测试:

输入样例:
参见题目功能说明。

输出样例:
参见题目功能说明。
整体输出顺序表时,每个数据后面一个空格。

顺序表的基本运算如下:
(1)初始化顺序表L
(2)依次插入a,b,c,d,e元素
(3)输出顺序表L:a b c d e
(4)顺序表L长度:5
(5)顺序表L为非空
(6)顺序表L的第3个元素:c
(7)元素a的位置:1
(8)在第4个元素位置上插入f元素
(9)输出顺序表L:a b c f d e
(10)删除L的第3个元素
(11)输出顺序表L:a b f d e
(12)释放顺序表L

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

完整代码

//顺序表运算算法
#include <stdio.h>
#include <stdlib.h>

#define MaxSize 50
typedef char ElemType;

typedef struct
{
    ElemType data[MaxSize];		//存放顺序表元素
    int length;					//存放顺序表的长度
} SqList;						//声明顺序表的类型

/**
 * 初始化顺序表L。
 */
void InitList(SqList * &L);

/**
 * 释放顺序表L。
 */
void DestroyList(SqList * &L);

/**
 * 判断顺序表L是否为空表。
 * 空表返回true,非空表返回false。
 */
bool ListEmpty(SqList * L);

/**
 * 返回顺序表L的元素个数。
 */
int ListLength(SqList * L);

/**
 * 输出顺序表L。
 */
void DispList(SqList * L);

/**
 * 获取顺序表L中第i(1≤i≤L->length)个元素,将其值存入e,然后返回true;
 * 如果不能获取到第i个元素,返回false。
 */
bool GetElem(SqList * L, int i, ElemType &e);

/**
 * 在顺序表L中查找元素e。
 * 如果存在e,则返回e的逻辑序号,否则返回0。
 */
int LocateElem(SqList * L,  ElemType e);

/**
 * 在顺序表L中第ii(1≤i≤L->length)个位置上插入元素e。
 * 插入成功,返回true。插入不成功,返回false。
 */
bool ListInsert(SqList * &L, int i,  ElemType e);

/**
 * 从顺序表L中删除第ii(1≤i≤L->length)个元素。
 * 删除成功,返回true。删除不成功,返回false。
 */
bool ListDelete(SqList * &L, int i, ElemType &e);

int main()
{
    SqList *L;
    ElemType e;
    printf("顺序表的基本运算如下:\n");
    printf("  (1)初始化顺序表L\n");
    InitList(L);
    printf("  (2)依次插入a,b,c,d,e元素\n");
    ListInsert(L, 1, 'a');
    ListInsert(L, 2, 'b');
    ListInsert(L, 3, 'c');
    ListInsert(L, 4, 'd');
    ListInsert(L, 5, 'e');
    printf("  (3)输出顺序表L:");
    DispList(L);
    printf("  (4)顺序表L长度:%d\n", ListLength(L));
    printf("  (5)顺序表L为%s\n", (ListEmpty(L) ? "空" : "非空"));
    GetElem(L, 3, e);
    printf("  (6)顺序表L的第3个元素:%c\n", e);
    printf("  (7)元素a的位置:%d\n", LocateElem(L, 'a'));
    printf("  (8)在第4个元素位置上插入f元素\n");
    ListInsert(L, 4, 'f');
    printf("  (9)输出顺序表L:");
    DispList(L);
    printf("  (10)删除L的第3个元素\n");
    ListDelete(L, 3, e);
    printf("  (11)输出顺序表L:");
    DispList(L);
    printf("  (12)释放顺序表L\n");
    DestroyList(L);
    return 0;
}

/* 请在下面填写代码 */
void InitList(SqList *&L)	//初始化线性表
{
    /****************Begin******************/
    L = (SqList *)malloc(sizeof(SqList));
    L->length = 0;
    /******************End******************/
}
void DestroyList(SqList *&L)  //销毁线性表
{
	/****************Begin******************/
    free(L);
    /******************End******************/
}
bool ListEmpty(SqList *L)	//判线性表是否为空表
{
	/****************Begin******************/
    return (L->length==0);
    /******************End******************/
}
int ListLength(SqList *L)	//求线性表的长度
{
	/****************Begin******************/
    return (L->length);
    /******************End******************/
}
void DispList(SqList *L)	//输出线性表
{
	/****************Begin******************/
    for(int i=0; i<L->length; i++) {
        printf("%c ", L->data[i]);
    }
    printf("\n");
    /******************End******************/
}
bool GetElem(SqList *L, int i, ElemType &e)	//求线性表中第i个元素值
{
	/****************Begin******************/
    if(i<1 || i>L->length) {
        return false;
    }
    e=L->data[i-1];
    return true;
    /******************End******************/
}
int LocateElem(SqList *L, ElemType e)	//查找第一个值域为e的元素序号
{
	/****************Begin******************/
    int i = 0;
    while(i<L->length && L->data[i]!=e) {
        i++;
    }
    if(i>=L->length){
        return 0;
    }else{
        return i+1;
    }
    /******************End******************/
}
bool ListInsert(SqList *&L, int i, ElemType e)	//插入第i个元素
{
	/****************Begin******************/
    int j;
    if(i<1 || i>((L->length)+1) || (L->length)==MaxSize) {
        return false;
    }
    i--;
    for(j=L->length; j>i; j--) {
        L->data[j] = L->data[j-1];
    }
    L->data[i] = e;
    L->length++;
    return true;
    /******************End******************/
}
bool ListDelete(SqList *&L, int i, ElemType &e)	//删除第i个元素
{
	/****************Begin******************/
    int j;
    if(i<1 || i>L->length) {
        return false;
    }
    i--;
    e = L->data[i];
    for(j=i; j<L->length-1; j++) {
        L->data[j] = L->data[j+1];
    }
    L->length--;
    return true;
    /******************End******************/
}

在这里插入图片描述

第2关:实现单链表各种基本运算的算法

任务描述

本关任务:实现单链表各种基本运算的算法。

目的: 领会单链表存储结构和掌握单链表中各种基本运算算法设计。
内容: 实现单链表的各种基本运算(假设单链表的元素类型ElemType为char),并在此基础上设计一个程序,完成如下功能:
(1)初始化单链表h。
(2)依次采用尾插法插入a、b、c、d、e元素。
(3)输出单链表h。
(4)输出单链表h长度。
(5)判断单链表h是否为空。
(6)输出单链表h的第3个元素。
(7)输出元素a的位置。
(8)在第4个元素位置上插入f元素。
(9)输出单链表h。
(10)删除单链表h的第3个元素。
(11)输出单链表h。
(12)释放单链表h。

编程要求

根据提示,在右侧编辑器Begin…End之间补充代码,实现单链表基本运算算法。

测试说明
平台会对你编写的代码进行测试:

输入样例:
参见题目功能说明。

输出样例:
参见题目功能说明。
整体输出单链表表时,每个数据后面一个空格。

单链表的基本运算如下:
(1)初始化单链表h
(2)依次采用尾插法插入a,b,c,d,e元素
(3)输出单链表h:a b c d e
(4)单链表h长度:5
(5)单链表h为非空
(6)单链表h的第3个元素:c
(7)元素a的位置:1
(8)在第4个元素位置上插入f元素
(9)输出单链表h:a b c f d e
(10)删除h的第3个元素
(11)输出单链表h:a b f d e
(12)释放单链表h

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

完整代码

//单链表运算算法
#include <stdio.h>
#include <stdlib.h>

typedef char ElemType;

typedef struct LNode {
	ElemType data;
	struct LNode *next;		//指向后继结点
} LinkNode;		 			//单链表结点类型

/**
 * 头插法建立单链表
 */
void CreateListF(LinkNode *&L, ElemType a[], int n);

/**
 * 尾插法建立单链表
 */
void CreateListR(LinkNode *&L, ElemType a[], int n);

/**
 * 初始化线性表
 */
void InitList(LinkNode *&L);

/**
 * 销毁线性表
 */
void DestroyList(LinkNode *&L);

/**
 * 判线性表是否为空表。空表返回true,否则返回false。
 */
bool ListEmpty(LinkNode *L);

/**
 * 求线性表的长度
 */
int ListLength(LinkNode *L);

/**
 * 输出线性表: 每个数据后面一个空格
 */
void DispList(LinkNode *L);

/**
 * 求线性表中第i个元素值。
 * 存在第i个数据结点,其值存入e,然后返回true。
 * 不存在第i个数据结点,返回false。
 */
bool GetElem(LinkNode *L, int i, ElemType &e);

/**
 * 查找第一个值域为e的元素序号。
 * 若存在,返回其逻辑序号;若不存在,返回0。
 */
int LocateElem(LinkNode *L, ElemType e);

/**
 * 插入第i个元素。
 * 插入成功,返回true;插入不成功,返回false。
 */
bool ListInsert(LinkNode *&L, int i, ElemType e);

/**
 * 删除第i个元素。
 * 如果第i个元素存在,其值存入e,返回true;
 * 如果第i个元素不存在,返回false。
 */
bool ListDelete(LinkNode *&L, int i, ElemType &e) ;

int main() {
	LinkNode *h;
	ElemType e;
	printf("单链表的基本运算如下:\n");
	printf("  (1)初始化单链表h\n");
	InitList(h);
	printf("  (2)依次采用尾插法插入a,b,c,d,e元素\n");
	ListInsert(h, 1, 'a');
	ListInsert(h, 2, 'b');
	ListInsert(h, 3, 'c');
	ListInsert(h, 4, 'd');
	ListInsert(h, 5, 'e');
	printf("  (3)输出单链表h:");
	DispList(h);
	printf("  (4)单链表h长度:%d\n", ListLength(h));
	printf("  (5)单链表h为%s\n", (ListEmpty(h) ? "空" : "非空"));
	GetElem(h, 3, e);
	printf("  (6)单链表h的第3个元素:%c\n", e);
	printf("  (7)元素a的位置:%d\n", LocateElem(h, 'a'));
	printf("  (8)在第4个元素位置上插入f元素\n");
	ListInsert(h, 4, 'f');
	printf("  (9)输出单链表h:");
	DispList(h);
	printf("  (10)删除h的第3个元素\n");
	ListDelete(h, 3, e);
	printf("  (11)输出单链表h:");
	DispList(h);
	printf("  (12)释放单链表h\n");
	DestroyList(h);
	return 0;
}

/* 请在下面编写程序代码 */

/**
 * 头插法建立单链表
 */
void CreateListF(LinkNode *&L, ElemType a[], int n) {
	/**************************Begin***************************/
    LinkNode *s;
    L = (LinkNode *)malloc(sizeof(LinkNode));  //为链表L分配内存空间,创建头结点
    L->next = NULL;   // 先将指向的地址为空,相当于头指针为空
    // 对数组处理
    for(int i=0; i<n; i++) {
        s = (LinkNode *)malloc(sizeof(LinkNode));  //为链表s分配内存空间
        s->data = a[i];   // 存入数据
        s->next = L->next;   // 指向下一节点
        L->next = s;  // 指向s
    }

	/***************************End****************************/
}

/**
 * 尾插法建立单链表
 */
void CreateListR(LinkNode *&L, ElemType a[], int n) {
	/**************************Begin***************************/
    LinkNode *s, *r;
    r = NULL;   
    for(int i=0; i<n; i++) {
        s = (LinkNode *)malloc(sizeof(LinkNode));
        s->data = a[i];
        s->next = NULL;

        if(r==NULL) {
            L = s;
            r = s;
        }else{
            r->next = s;
            r = s;
        }
    }
    r->next = NULL;
    
    /***************************End****************************/
}

/**
 * 初始化线性表
 */
void InitList(LinkNode *&L) {
	L = (LinkNode *)malloc(sizeof(LinkNode)); //创建头结点
	L->next = NULL;				//单链表置为空表
}

/**
 * 销毁线性表
 */
void DestroyList(LinkNode *&L) {
	LinkNode *pre = L, *p;
	while (p != NULL) {
        p = pre->next;
		free(pre);
		pre = p;				
	}
	L = NULL;
}

/**
 * 判线性表是否为空表。空表返回true,否则返回false。
 */
bool ListEmpty(LinkNode *L) {
    /**************************Begin***************************/
	return (L == NULL);

    /**************************End***************************/
}

/**
 * 求线性表的长度
 */
int ListLength(LinkNode *L) {
	/**************************Begin***************************/
    int i;
    LinkNode *p = L;  // p指向头节点
    for(i=0; p->next != NULL; i++) {
        p = p->next;
    }
    return i;

	/***************************End****************************/
}

/**
 * 输出线性表: 每个数据后面一个空格
 */
void DispList(LinkNode *L) {
	/**************************Begin***************************/    
    LinkNode *p = L;	//p指向首结点
    while (p != NULL&&p->next!=NULL) {		//p不为NULL,输出p结点的data域       
        printf("%c ", p->data);
        p = p->next;			//p移向下一个结点
    }
    printf("\n");
    /***************************End****************************/
}

/**
 * 求线性表中第i个元素值。
 * 存在第i个数据结点,其值存入e,然后返回true。
 * 不存在第i个数据结点,返回false。
 */
bool GetElem(LinkNode *L, int i, ElemType &e) {
	/**************************Begin***************************/
    LinkNode *p=L;  // 从头开始遍历
    int count = 0;  // 用于计数当前遍历到的结点序号
    while (p != NULL) {
        count++;
        if (count == i) {   // 如果当前结点序号等于i,则将该结点的数据域值存入e中
            e = p->data;
            return true;
        }
        p = p->next;
        
    }
    return false;  // 遍历完整个链表仍然没有找到第i个元素,返回false
    
    /***************************End****************************/
}

/**
 * 查找第一个值域为e的元素序号。
 * 若存在,返回其逻辑序号;若不存在,返回0。
 */
int LocateElem(LinkNode *L, ElemType e) {
	/**************************Begin***************************/
    int count = 1;
    while (L != NULL) {
        if(L->data == e) {
            return count;
        }
        L = L->next;
        count++;
    }
    return 0;
    
	/***************************End****************************/
}

/**
 * 插入第i个元素。
 * 插入成功,返回true;插入不成功,返回false。
 */
bool ListInsert(LinkNode *&L, int i, ElemType e) {
	/**************************Begin***************************/
    if(i<1 || L==NULL) {
        return false;
    }
    
    LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));
    s->data = e;
    s->next = NULL;

    if(i==1) {  // 如果插入到头部
        s->next = L;
        L = s;
    } else {  // 如果插入到中间或尾部
        LinkNode *p = L;  // 当前指针结点
        int count = 1;
        while(p!=NULL&&count<i-1) {
            p = p->next;
            count++;
        }
        if(p == NULL) {
            return false; // 到达链表尾部,无法插入
        }
        s->next = p->next;
        p->next = s;
    }
    return true;  // 成功插入返回true

	/***************************End****************************/
}

/**
 * 删除第i个元素。
 * 如果第i个元素存在,其值存入e,返回true;
 * 如果第i个元素不存在,返回false。
 */
bool ListDelete(LinkNode *&L, int i, ElemType &e) {
	/**************************Begin***************************/
    if(L==NULL || i<1) {
        return false;
    }

    int count = 1;
    LinkNode *p = L;

    while(p!=NULL && count<i-1) {   
        p = p->next;
        count++;
    }

    if(p==NULL) {
        return false;
    }
    
    e = p->data;
    LinkNode *q = p->next;
    p->next = q->next;
    free(q);

    return true;

	/***************************End****************************/
}
 

在这里插入图片描述

第3关:移除顺序表中所有值等于x的元素

任务描述

本关任务:假设一个线性表采用顺序表表示,设计一个算法,删除其中所有值等于x的所有元素,要求算法的时间复杂度为O(n),空间复杂度为O(1)。

编程要求

根据提示,在右侧编辑器补充代码,完成函数removeElems(SqList* &L, ElemType x)。

测试说明
输入
输入包括3行。
第一行为顺序表中元素的个数n。
第二行为空格隔开的n个整数。
第三行为需要删除的元素x。

输出
输出包含2行。
第一行输出顺序表所有元素,每个元素后面一个空格。
第二行为删除x后顺序表所有元素,每个元素后面一个空格。

样例输入1
10
1 2 2 1 0 2 4 2 3 1
2

样例输出1
顺序表L中的元素为: 1 2 2 1 0 2 4 2 3 1
移除 2 后顺序表L中的元素为: 1 1 0 4 3 1

样例输入2
4
3 2 2 3
3

样例输出2
顺序表L中的元素为: 3 2 2 3
移除 3 后顺序表L中的元素为: 2 2

样例输入3
8
0 1 2 2 3 0 4 2
2

样例输出3
顺序表L中的元素为: 0 1 2 2 3 0 4 2
移除 2 后顺序表L中的元素为: 0 1 3 0 4

提示
1 <= 顺序表长度 <= 100
0 <= 元素值 <= 50
0 <= x <= 100

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

完整代码

#include "sqlist.h"

/**
 * 移除顺序表中值为x的所有元素
 */
void removeElements(SqList *&L, ElemType x);

int main()
{
	int n, *a, x;

	scanf("%d", &n);

	a = (int*)malloc(sizeof(int) * n);
	for (int i = 0; i < n; i++)
		scanf("%d", &a[i]);

	SqList *L;
	CreateList(L, a, n);
	printf("顺序表L中的元素为: "); DispList(L);

	scanf("%d", &x);	//输入需要移除的元素

	removeElements(L, x);
	printf("移除 %d 后顺序表L中的元素为: ", x); DispList(L);

	return 0;
}

/**
 * 移除顺序表中值为x的所有元素
 */
void removeElements(SqList *&L, ElemType x)
{
	//请在下面编写代码
	/***************************Begin**********************/
    int i=0;
    int j=0;
    while(i<L->length) {
        if(L->data[i]!=x) {
           L->data[j] = L->data[i];
           j++;
        }
        i++;
    }
    L->length = j;


   /****************************End***********************/
} 

在这里插入图片描述

第4关:逆置顺序表

任务描述

在这里插入图片描述

编程要求

根据提示,在右侧编辑器补充函数rev的代码,使用顺序表L的空间就地逆置L。

测试说明
平台会对你编写的代码进行测试:

输入格式
输入包括两行。
第一行为顺序表中元素个数n。
第二行为空格隔开的n个整数。

输出格式
输出包括两行。
第一行为顺序表逆置之前的元素。每个数据后一个空格。
第二行为顺序表逆置之后的元素。每个数据后一个空格。

样例输入
5
1 2 3 4 5

样例输出
1 2 3 4 5
5 4 3 2 1

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

完整代码

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

#include "sqlist.h"

/**
 * 就地逆置顺序表
 */
void rev(SqList* &L) {
	//请在下面编写代码
	/******************Begin******************/
	int k;
    int i=0;
    int j=(L->length)-1;
    while(i<L->length/2&&i<=j) {
        k = L->data[i];
        L->data[i] = L->data[j];
        L->data[j] = k;
        i++;
        j--;
    }
    
    
	/*******************End*******************/
}

int main(int argc, char const *argv[])
{
	int n;
	scanf("%d", &n);
	int *a = (int*)malloc(sizeof(int) * n);
	for (int i = 0; i < n; i++)
		scanf("%d", &a[i]);
	SqList* L;
	InitList(L);		//初始化顺序表
	CreateList(L, a, n);//创建顺序表
	DispList(L);		//输出顺序表
	rev(L);				//逆置顺序表
	DispList(L);		//输出逆置后的顺序表
	DestroyList(L);		//销毁顺序表
	free(a);			//是否数组a
	return 0;
} 

在这里插入图片描述

第5关:删除有序顺序表中的重复项

任务描述

本关任务:编写一个效率尽可能高的算法,删除有序顺序表中的重复元素,重复的元素只保留一个。元素的 相对顺序 应该保持 一致 。

编程要求

根据提示,在右侧编辑器补充完成函数void remove_duplicates(SqList* &L)的代码,删除有序顺序表中的重复项。

测试说明
平台会对你编写的代码进行测试:

输入格式
输入包括两行。
第一行为顺序表中元素个数n。
第二行为空格隔开的n个整数。

输出格式
输出包括两行。
第一行为有序顺序表原有的元素。每个数据后一个空格。
第二行为删除有序顺序表重复项之后的元素。每个数据后一个空格。

样例输入1
3
1 1 2

样例输出1
1 1 2
1 2

样例输入2
10
0 0 1 1 1 2 2 3 3 4

样例输出2
0 0 1 1 1 2 2 3 3 4
0 1 2 3 4

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

完整代码

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

#include "sqlist.h"

/**
 * 删除有序顺序表中的重复项
 */
void remove_duplicates(SqList* &L) {
	//请在下面编写代码
	/******************Begin******************/
    int k;
    int j=0;
   
    for(k=1; k<L->length; k++) {  // 看是否有重复的项
        if(L->data[j] != L->data[k]) {
            j++;
            L->data[j] = L->data[k];
        }
    }
    L->length = j+1;
    

    
	/*******************End*******************/
}

int main(int argc, char const *argv[])
{
	int n;
	scanf("%d", &n);
	int *a = (int*)malloc(sizeof(int) * n);
	for (int i = 0; i < n; i++)
		scanf("%d", &a[i]);
	SqList* L;
	InitList(L);			//初始化顺序表
	CreateList(L, a, n);	//创建顺序表
	DispList(L);			//输出顺序表
	remove_duplicates(L);	//删除有序顺序表中的重复项
	DispList(L);			//输出顺序表
	DestroyList(L);			//销毁顺序表
	free(a);				//释放数组
	return 0;
} 

在这里插入图片描述

第6关:拆分单链表

任务描述

在这里插入图片描述
拆分单链表
请添加图片描述

相关知识

为了完成本关任务,你需要掌握:1.单链表的基本概念,2.如何创建、遍历单链表。

单链表的基本概念
单链表是线性表的链式存储结构实现。如下图所示:
单链表
请添加图片描述
单链表的头结点
为了操作方便,有时候会在单链表第一个元素结点的前面增加一个附加头结点,如下图所示:
带附加头结点的单链表
请添加图片描述

单链表增加一个头结点的优点如下:

首结点的操作和表中其他结点的操作相一致,无需进行特殊处理;
无论链表是否为空,都有一个头结点,因此空表和非空表的处理也就统一了。

单链表结点类型定义
单链表中结点类型LinkNode的定义如下:

typedef struct LNode  //定义单链表结点类型
{  
   ElemType data;     //存储元素
   struct LNode *next; //指向后继结点
}  LinkNode;

单链表的特点
单链表的特点:当访问过一个结点 p 后,只能接着访问它的后继结点,而无法访问它的前驱结点。

单链表插入一个结点
插入操作:将值为x的新结点s插入到p结点之后。
特点:只需修改相关结点的指针域,不需要移动结点。
插入操作如下图所示:
单链表插入结点
请添加图片描述
单链表删除一个结点
删除操作:删除p结点之后的一个结点。
特点:只需修改相关结点的指针域,不需要移动结点。
删除操作如下图所示:
请添加图片描述

删除操作的语句如下:

p->next = p->next->next;

创建单链表

头插法建立单链表
从一个空表开始,创建一个头结点。
依次读取线性表中的元素,生成新结点s。
将新结点插入到当前链表的表头上,直到结束为止。

头插法建立单链表如下图所示:
请添加图片描述
建表语句如下:

void CreateListF(LinkNode *&L, ElemType a[], int n)
{
    LinkNode *s;
    L = (LinkNode *)malloc(sizeof(LinkNode));      //创建头结点
    L->next = NULL;
    for (int i = 0; i < n; i++)
    {
        s = (LinkNode *)malloc(sizeof(LinkNode)); //创建新结点s
        s->data = a[i];
        s->next = L->next;            //将结点s插在原开始结点之前,头结点之后
        L->next = s;
    }
}

尾插法建立单链表
从一个空表开始,创建一个头结点。
依次读取线性表中的元素,生成新结点s
将新结点插入到当前链表的表尾上,直到结束为止。

尾插法建立单链表如下图所示:
请添加图片描述
建表语句如下:

void CreateListR(LinkNode *&L, ElemType a[], int n)
{
    LinkNode *s, *r;
    L = (LinkNode *)malloc(sizeof(LinkNode));      //创建头结点
    L->next = NULL;
    r = L;                    //r始终指向终端结点,开始时指向头结点
    for (int i = 0; i < n; i++)
    {
        s = (LinkNode *)malloc(sizeof(LinkNode)); //创建新结点s
        s->data = a[i];
        r->next = s;        //将结点s插入结点r之后
        r = s;
    }
    r->next = NULL;            //终端结点next域置为NULL
}

输出单链表
逐一扫描单链表L的每个数据结点,并显示各结点的data域值。
请添加图片描述

编程要求

根据提示,在右侧编辑器补充代码,完成函数void split(LinkNode *&L, LinkNode *&L1, LinkNode *&L2),将单链表L拆分为L1和L2。

测试说明
平台会对你编写的代码进行测试:

输入格式
输入包括两行。
第一行为单链表中元素个数n。
第二行为空格隔开的n个整数。

输出格式
输出包括四行。
第一行为单链表的元素。每个数据后一个空格。
第二行显示提示信息。
第三行显示单链表L1中的元素。每个数据后一个空格。
第四行显示单链表L2中的元素。每个数据后一个空格。

样例输入
6
1 2 3 4 5 6

样例输出
L: 1 2 3 4 5 6
L->L1,L2
L1: 1 3 5
L2: 6 4 2

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

完整代码

#include "linklist.h"

//将单链表L拆分成两个单链表L1和L2。
void split(LinkNode *&L, LinkNode *&L1, LinkNode *&L2)
{
	//请在下面编写代码
	/**********************Begin**********************/
    LinkNode *p = L->next, *q, *r1;
    L1 = L;
    r1 = L1;   // r1指向L1的尾结点
    L2 = (LinkNode *)malloc(sizeof(LinkNode));
    L2->next = NULL;
	
    while(p!=NULL) {
        r1->next = p;
        r1 = p;
        p = p->next;
        q = p->next;
        p->next = L2->next;
        L2->next = p;
        p = q;
    
    }
    r1->next = NULL;
    
	/***********************End***********************/
}

int main()
{
	LinkNode *L, *L1, *L2;
	int n;
	scanf("%d", &n);
	ElemType a[n];
	for (int i = 0; i < n; i++)
		scanf("%d", &a[i]);
	InitList(L);					//初始化单链表L
	InitList(L1);					//初始化单链表L1
	InitList(L2);					//初始化单链表L2
	CreateListR(L, a, n);			//创建单链表L
	printf("L: "); DispList(L);		//输出单链表L
	printf("L->L1,L2\n");
	split(L, L1, L2);				//单链表L拆分为L1和L2
	printf("L1: "); DispList(L1);	//输出单链表L1
	printf("L2: "); DispList(L2);	//输出单链表L2
	DestroyList(L1);				//销毁单链表L1
	DestroyList(L2);				//销毁单链表L2
	return 0;
}
 

在这里插入图片描述

第7关:删除单链表中值最大的结点

任务描述

本关任务:设计一个算法,删除一个单链表L中元素值最大的结点(假设最大值结点是唯一的)。

编程要求

根据提示,在右侧编辑器补充代码,完成函数void del_max_node(LinkNode *&L),其中L为带头结点的单链表,函数功能是删除单链表L中值最大的结点。

测试说明

平台会对你编写的代码进行测试:

输入格式
输入包括两行。
第一行为单链表中元素个数n。
第二行为空格隔开的n个整数。

输出格式
输出包括两行。
第一行为单链表的元素。每个数据后一个空格。
第二行为删除值最大的元素之后的单链表。每个数据后一个空格。

样例输入1
6
3 0 2 7 8 6

样例输出1
L: 3 0 2 7 8 6
L: 3 0 2 7 6

样例输入2
1
3

样例输出2
L: 3
L: NULL

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

完整代码

#include "linklist.h"

/**
 * 删除单链表中最大元素的结点。假定值最大的结点唯一。
 */
void del_max_node(LinkNode *&L)
{
	//请在下面编写代码
	/******************Begin******************/
	LinkNode *p=L->next, *pre=L, *maxp=p, *maxpre=pre;

    while(p!=NULL) {
        if(maxp->data<p->data) {
            maxp = p;
            maxpre = pre;
        }
        pre = p;
        p = p->next;
    }
    maxpre->next = maxp->next;
    free(maxp);
    
	/*******************End*******************/
}

int main()
{
	LinkNode *L;
	// int n = 10;
	// ElemType a[] = {1, 3, 2, 9, 0, 4, 7, 6, 5, 8};
	int n;
	scanf("%d", &n);
	int *a = (int*)malloc(sizeof(int) * n);
	for (int i = 0; i < n; i++)
		scanf("%d", &a[i]);
	CreateListR(L, a, n);		//创建单链表
	printf("L: "); DispList(L);	//输出单链表
	del_max_node(L);			//删除单链表中最大值结点
	printf("L: "); DispList(L);	//输出单链表
	DestroyList(L);				//销毁单链表
	free(a);					//释放数组
	return 0;
} 

在这里插入图片描述

第8关:单链表插入排序

任务描述

本关任务:有一个带头结点的单链表L(至少有一个数据结点),设计一个算法使其元素递增有序排列。

相关知识

单链表结点类型定义:

typedef int ElemType;
typedef struct LNode
{
    ElemType data;
    struct LNode *next;        //指向后继结点
} LinkNode;                    //声明单链表结点类型

编程要求

根据提示,在右侧编辑器补充代码,完成函数void sort_list(LinkNode *&L),该函数功能是对带头结点的单链表L进行插入排序,使其递增有序。

测试说明

平台会对你编写的代码进行测试:

输入格式
输入包括两行。
第一行为一个整数n。
第二行为空格隔开的n个整数。

输出格式
输出包括两行。
第一行为排序之前的单链表。每个数据后一个空格。
第二行为递增排序之后的单链表。每个数据后一个空格。

样例输入
10
1 3 2 9 0 4 7 6 5 8

样例输出
L: 1 3 2 9 0 4 7 6 5 8
L: 0 1 2 3 4 5 6 7 8 9

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

完整代码

#include "linklist.h"

/**
 * 单链表L递增(插入)排序
 */
void sort_list(LinkNode *&L)
{
	//请在下面编写代码
	/******************Begin******************/
    LinkNode *p, *pre, *q;
    p = L->next->next;
    L->next->next = NULL;

    while(p!=NULL) {
        q = p->next;
        pre = L;

        while(pre->next!=NULL && pre->next->data<p->data) {
            pre = pre->next;
        }
        p->next = pre->next;
        pre->next = p;
        p =q; 
    }
	
	/*******************End*******************/
}

int main()
{
	LinkNode *L;
	// int n = 10;
	// ElemType a[] = {1, 3, 2, 9, 0, 4, 7, 6, 5, 8};
	int n;
	scanf("%d", &n);
	int *a = (int*)malloc(sizeof(int) * n);
	for (int i = 0; i < n; i++)
		scanf("%d", &a[i]);
	CreateListR(L, a, n);		//创建单链表
	printf("L: "); DispList(L);	//输出单链表
	sort_list(L);				//单链表递增排序
	printf("L: "); DispList(L);	//输出排序后的单链表
	DestroyList(L);				//销毁单链表
	free(a);					//释放数组
	return 0;
} 

在这里插入图片描述

第9关:逆置单链表

任务描述

在这里插入图片描述
请添加图片描述

编程要求

根据提示,在右侧编辑器补充代码,完成函数void rev_list(LinkNode *&L);该函数功能为对带头结点的单链表L进行逆置。

测试说明

平台会对你编写的代码进行测试:

输入格式
输入包括两行。
第一行为单链表中元素个数n。
第二行为空格隔开的n个整数。

输出格式
输出包括一行,为单链表逆置之后的元素。每个数据后一个空格。

样例输入
5
1 2 3 4 5

样例输出
L: 5 4 3 2 1

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

完整代码

#include "linklist.h"

/**
 * 逆置单链表
 */
void rev_list(LinkNode *&L)
{
	//请在下面编写代码
	/******************Begin******************/
	LinkNode *p, *q;  // 尾插法
    p = L->next;
    L->next = NULL;
    while(p!=NULL) {
        q = p;
        p = p->next;
        q->next = L->next;
        L->next = q;
    }

	/*******************End*******************/
}

//尾插法建立单链表
void CreateListR(LinkNode *&L, ElemType a[], int n)
{
	LinkNode *s, *r;
	L = (LinkNode *)malloc(sizeof(LinkNode));  	//创建头结点
	L->next = NULL;
	r = L;					//r始终指向终端结点,开始时指向头结点
	for (int i = 0; i < n; i++)
	{
		s = (LinkNode *)malloc(sizeof(LinkNode)); //创建新结点s
		s->data = a[i];
		r->next = s;		//将结点s插入结点r之后
		r = s;
	}
	r->next = NULL;			//终端结点next域置为NULL
}

//初始化单链表
void InitList(LinkNode *&L)
{
	L = (LinkNode *)malloc(sizeof(LinkNode));  	//创建头结点
	L->next = NULL;
}

//销毁单链表
void DestroyList(LinkNode *&L)
{
	LinkNode *pre = L, *p = pre->next;
	while (p != NULL)
	{
		free(pre);
		pre = p;
		p = pre->next;
	}
	free(pre);	//此时p为NULL,pre指向尾结点,释放它
}

//输出单链表
void DispList(LinkNode *L)
{
	LinkNode *p = L->next;
	while (p != NULL)
	{
		printf("%d ", p->data);
		p = p->next;
	}
	printf("\n");
}

在这里插入图片描述

第10关:移除链表元素

任务描述

本关任务:给你一个带附加头结点L的单链表和一个整数 val ,请你删除链表中所有值为 val 的结点。
例如,下图所示的单链表L,val=6,删除所有值为6的结点。
请添加图片描述

编程要求

根据提示,在右侧编辑器补充代码,完成函数void remove_elements(LinkNode *&L, ElemType val),该函数功能为:删除L中所有值为val的结点。

测试说明

平台会对你编写的代码进行测试:

输入格式
输入包括两行。
第一行有两个空格分隔的整数。第一个整数为单链表结点数量n,第二个数为需要删除的元素val。
第二行为空格隔开的n个整数。

输出格式
输出包括一行。为删除val后的单链表,每个数据后一个空格。

样例输入
7 6
1 2 6 3 4 5 6

样例输出
L->1 2 3 4 5

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

完整代码

#include "linklist.h"

/**
 * 删除链表元素: 删除L中所有值为val的结点
 */
void remove_elements(LinkNode *&L, ElemType val)
{
	//请在下面编写代码
	/******************Begin******************/
    LinkNode *cur = L, *prev=L, *p;

    while(cur != NULL) {  // 遍历链表
        if(cur->data == val) {
            p = cur->next;  // 保存cur的下一个结点位置
            if(L == cur) {  // 判断cur是否是首结点
                L = p;
            }else{
                prev->next = p;  // 将cur上一节点和下一结点相连
            }
            free(cur);  // 删除等于val的结点
            cur = p;
        }else if(cur->data != val){
            prev = cur;
            cur = prev->next;  // 将cur上一结点和cur下一结点相连
        }
    }


	/*******************End*******************/
}


//尾插法建立单链表
void CreateListR(LinkNode *&L, ElemType a[], int n)
{
	LinkNode *s, *r;
	L = (LinkNode *)malloc(sizeof(LinkNode));  	//创建头结点
	L->next = NULL;
	r = L;					//r始终指向终端结点,开始时指向头结点
	for (int i = 0; i < n; i++)
	{
		s = (LinkNode *)malloc(sizeof(LinkNode)); //创建新结点s
		s->data = a[i];
		r->next = s;		//将结点s插入结点r之后
		r = s;
	}
	r->next = NULL;			//终端结点next域置为NULL
}

//初始化单链表
void InitList(LinkNode *&L)
{
	L = (LinkNode *)malloc(sizeof(LinkNode));  	//创建头结点
	L->next = NULL;
}

//销毁单链表
void DestroyList(LinkNode *&L)
{
	LinkNode *pre = L, *p = pre->next;
	while (p != NULL)
	{
		free(pre);
		pre = p;
		p = pre->next;
	}
	free(pre);	//此时p为NULL,pre指向尾结点,释放它
}

//输出单链表
void DispList(LinkNode *L)
{
	if (L->next == NULL) {
		printf("NULL\n");
		return;
	}
	LinkNode *p = L->next;
	while (p != NULL)
	{
		printf("%d ", p->data);
		p = p->next;
	}
	printf("\n");
} 

在这里插入图片描述

第11关:约瑟夫环

任务描述

本关任务:n个人围成一圈,按顺序从1到n进行编号,初始时从编号为1的人开始按1、2、3…顺序报数,报数到m(1≤m≤n)时该人退出到圈外,接着从出圈时的下一个位置开始从1开始重新进行报数,报数到m时的人再退出到圈外,以此类推。
请按退出顺序输出每个退出人的原编号。

编程要求

根据提示,在右侧编辑器补充代码,补充完成函数void Jesuphus(LinkNode *&L, int n, int m),其中L为不带附加头结点的循环单链表的头指针,n为圈中人的个数,m为报数的值。

测试说明

平台会对你编写的代码进行测试:

输入格式
输入只有一行,为n和m。1≤n≤3000,1≤m≤n。

输出格式
输出包含一行,为退出到圈外的人的编号,编号之间以一个空格分隔。

样例输入1
10 3

样例输出1
3 6 9 2 7 1 8 5 10 4

样例输入2
7 4

样例输出1
4 1 6 5 7 3 2

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

完整代码

#include "linklist.h"

/**
 * 约瑟夫环:L为不带附带头结点的循环单链表的头指针
 */
void Jesuphus(LinkNode *&L, int n, int m)
{
	//请在下面编写代码
	/******************Begin******************/
	LinkNode *r, *p;
    p = L;

    while(p->next!=p){
        for(int i=1; i<m; i++){
            r = p;
            p = p->next;
        }

        printf("%d ", p->data);
        r->next = p->next;
        p = p->next;
    }
    printf("%d", p->data);

	/*******************End*******************/
}

//尾插法建立循环单链表
void CreateListR(LinkNode *&L, ElemType a[], int n)
{
	LinkNode *s, *r;
	L = (LinkNode *)malloc(sizeof(LinkNode));  	//创建头结点
	L->data = a[0];
	L->next = NULL;
	r = L;					//r始终指向终端结点,开始时指向头结点
	for (int i = 1; i < n; i++)
	{
		s = (LinkNode *)malloc(sizeof(LinkNode)); //创建新结点s
		s->data = a[i];
		r->next = s;		//将结点s插入结点r之后
		r = s;
	}
	r->next = L;			//形成循环单链表
}

//输出循环单链表
void DispList(LinkNode *L)
{
	LinkNode *p = L;
	while (p->next != L)
	{
		printf("%d ", p->data);
		p = p->next;
	}
	printf("%d\n", p->data); //打印最后一个结点的值
}

在这里插入图片描述

第12关:链表的中间结点

任务描述

本关任务:给定一个头结点为 L 的非空单链表,返回链表的中间结点。

如果有两个中间结点,则返回第二个中间结点。

示例一:
输入:1 2 3 4 5
输出:返回的结点值为 3 。

示例二:
输入:1 2 3 4 5 6
输出:返回的结点值为 4。
由于该链表有两个中间结点,值分别为 3 和 4,我们返回第二个结点 4。

编程要求

根据提示,在右侧编辑器补充代码,完成函数LinkNode* middleNode(LinkNode *L),该函数的功能是返回链表的中间结点。其中L为不带附加头结点的单链表的头指针。

测试说明

平台会对你编写的代码进行测试:

测试输入:
1 2 3 4 5
预期输出:
3

测试输入:
1 2 3 4 5 6
预期输出:
4

提示:给定链表的结点数介于 1 和 100 之间。

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

完整代码

#include "linklist.h"

/**
 * 返回链表的中间结点。L为不带附加头结点的单链表的头指针。
 */
LinkNode* middleNode(LinkNode *L)
{
	//请在下面编写代码
	/******************Begin******************/
    if(L->next==NULL){
        return L;
    }
    LinkNode *fast=L; // 走两步
    LinkNode *slow=L; // 走一步

    while(fast!=NULL && fast->next!=NULL){
        slow = slow->next;
        fast = fast->next->next;
    }

    return slow;
    
	
	/*******************End*******************/
}

//尾插法建立不带附加头结点的单链表
void CreateListR(LinkNode *&L, ElemType a[], int n)
{
	LinkNode *s, *r;
	L = (LinkNode *)malloc(sizeof(LinkNode));  	//创建头结点
	L->data = a[0];
	L->next = NULL;
	r = L;					//r始终指向终端结点,开始时指向头结点
	for (int i = 1; i < n; i++)
	{
		s = (LinkNode *)malloc(sizeof(LinkNode)); //创建新结点s
		s->data = a[i];
		r->next = s;		//将结点s插入结点r之后
		r = s;
	}
	r->next = NULL;			//单链表收尾
}

//输出单链表
void DispList(LinkNode *L)
{
	LinkNode *p = L;
	while (p != NULL)
	{
		printf("%d ", p->data);
		p = p->next;
	}
	printf("\n");
} 

在这里插入图片描述

第13关:回文链表

任务描述
本关任务:给你一个单链表的头结点 L ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。
示例一:
请添加图片描述
输出:YES

示例二:
请添加图片描述
输出:NO

编程要求

根据提示,在右侧编辑器补充代码,完成函数bool isPalindrome(LinkNode *L),该函数功能是判断链表是否为回文链表。如果是,返回 true ;否则,返回 false 。其中 L为不带附加头结点的单链表的头指针。

测试说明

平台会对你编写的代码进行测试:

测试输入:
1 2 2 1
预期输出:
YES

测试输入:
1 2
预期输出:
NO

提示:

链表中节点数目在范围[1,10^ 3 ] 内。
0 <= Node.val <= 9。

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

完整代码

#include "linklist.h"

/**
 * 判断链表是否为回文链表。如果是,返回 true ;否则,返回 false 。
 * L为不带附加头结点的单链表的头指针。
 */
bool isPalindrome(LinkNode *L)
{
	//请在下面编写代码
	/******************Begin******************/
	if (L == NULL || L->next == NULL) {
        return true;  // 空链表或只有一个节点的链表都是回文链表
    }

    // 使用快慢指针找到链表的中间节点
    LinkNode *slow = L;
    LinkNode *fast = L;
    while (fast->next != NULL && fast->next->next != NULL) {
        slow = slow->next;
        fast = fast->next->next;
    }

    // 反转链表的后半部分
    LinkNode *prev = NULL;
    LinkNode *curr = slow->next;
    while (curr != NULL) {
        LinkNode *next = curr->next;
        curr->next = prev;
        prev = curr;
        curr = next;
    }

    // 比较前半部分和反转后的后半部分是否相等
    LinkNode *p1 = L;
    LinkNode *p2 = prev;
    while (p1 != NULL && p2 != NULL) {
        if (p1->data != p2->data) {
            return false;
        }
        p1 = p1->next;
        p2 = p2->next;
    }

    return true;

	/*******************End*******************/
}

//尾插法建立不带附加头结点的单链表
void CreateListR(LinkNode *&L, ElemType a[], int n)
{
	LinkNode *s, *r;
	L = (LinkNode *)malloc(sizeof(LinkNode));  	//创建头结点
	L->data = a[0];
	L->next = NULL;
	r = L;					//r始终指向终端结点,开始时指向头结点
	for (int i = 1; i < n; i++)
	{
		s = (LinkNode *)malloc(sizeof(LinkNode)); //创建新结点s
		s->data = a[i];
		r->next = s;		//将结点s插入结点r之后
		r = s;
	}
	r->next = NULL;			//单链表收尾
}

//输出单链表
void DispList(LinkNode *L)
{
	LinkNode *p = L;
	while (p != NULL)
	{
		printf("%d ", p->data);
		p = p->next;
	}
	printf("\n");
} 

在这里插入图片描述

第14关:中位数

任务描述

本关任务:一个长度为L(L≥1)的升序序列S,处在第 ⌈L/2⌉个位置的数称为S的中位数。
例如:若序列S1=(11,13,15,17,19),则S1的中位数是15。
两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若S2=(2,4,6,8,20),则S1和S2的中位数是11。
现有两个等长的升序序列A和B,试设计一个在时间和空间两方面都尽可能高效的算法,找出两个序列A和B的中位数。

编程要求

根据提示,在右侧编辑器补充代码,完成函数ElemType find_median(SqList *A, SqList *B),该函数功能为求两个等长的有序顺序表的中位数并返回。

测试说明

平台会对你编写的代码进行测试:

测试输入:
5
11 13 15 17 19
2 4 6 8 20
预期输出:
11

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

完整代码

#include "sqlist.h"

/**
 * 求两个等长的有序顺序表的中位数。
 */
ElemType find_median(SqList *A, SqList *B)
{
	//请在下面编写代码
	/******************Begin******************/
    int i=0, j=0, k=0;
    while(i<A->length && j<B->length){
        k++;
        if(A->data[i] < B->data[j]){
            if(k==A->length)
                return A->data[i];
            i++;
        }else{
            if(k==B->length){
                return B->data[j];
            }
            j++;
        }
        
    }
    
    
	/*******************End*******************/
}

ElemType a[MaxSize];
ElemType b[MaxSize];

int main()
{
	SqList *L1, *L2;
	int n;
	scanf("%d", &n);
	for (int i = 0; i < n; i++)scanf("%d", &a[i]);
	for (int i = 0; i < n; i++)scanf("%d", &b[i]);
	CreateList(L1, a, n);
	CreateList(L2, b, n);
	printf("L1,L2的中位数:%d\n", find_median(L1, L2));
	return 0;
}
 

在这里插入图片描述

第15关:合并两个有序链表

任务描述

本关任务:将两个升序链表合并为一个新的 升序 链表。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
请添加图片描述

编程要求

根据提示,在右侧编辑器补充代码,完成函数void mergeTwoLists(LinkNode* &L, LinkNode* L1, LinkNode* L2),该函数的功能是:合并两个有序链表。L1和L2为不带附加头结点的单链表的头指针。L为合并后的单链表的头指针。

测试说明

平台会对你编写的代码进行测试:

测试输入:
3 3
1 2 4
1 3 4
预期输出:
1 1 2 3 4 4

提示:

两个链表的节点数目范围是 [1, 1000]
L1 和 L2 均按 非递减顺序 排列。

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

完整代码

#include "linklist.h"

/**
 * 合并两个有序链表。L1和L2为不带附加头结点的单链表的头指针。
 * L为合并后的单链表的头指针。
 */
void mergeTwoLists(LinkNode* &L, LinkNode *L1, LinkNode* L2)
{
	//请在下面编写代码
	/******************Begin******************/
	LinkNode *p1=L1,*p2=L2,*r,*s;
    L=(LinkNode*)malloc(sizeof(LinkNode));
    r=L;
    while(p1!=NULL&&p2!=NULL)
    {
        if(p1->data<p2->data)
        {
            s=(LinkNode*)malloc(sizeof(LinkNode));
            s->data=p1->data;
            r->next=s;
            r=s;
            p1=p1->next;
        }
        else
        {
            s=(LinkNode*)malloc(sizeof(LinkNode));
            s->data=p2->data;
            r->next=s;
            r=s;
            p2=p2->next;
        }
    }
    while(p1!=NULL)
    {
        s=(LinkNode*)malloc(sizeof(LinkNode));
        s->data=p1->data;
        r->next=s;
        r=s;
        p1=p1->next;
    }
    while(p2!=NULL)
    {
        s=(LinkNode*)malloc(sizeof(LinkNode));
        s->data=p2->data;
        r->next=s;
        r=s;
        p2=p2->next;
    }
    r->next=NULL;
    L=L->next;

	
	/*******************End*******************/
}

//尾插法建立不带附加头结点的单链表
void CreateListR(LinkNode *&L, ElemType a[], int n)
{
	LinkNode *s, *r;
	L = (LinkNode *)malloc(sizeof(LinkNode));  	//创建头结点
	L->data = a[0];
	L->next = NULL;
	r = L;					//r始终指向终端结点,开始时指向头结点
	for (int i = 1; i < n; i++)
	{
		s = (LinkNode *)malloc(sizeof(LinkNode)); //创建新结点s
		s->data = a[i];
		r->next = s;		//将结点s插入结点r之后
		r = s;
	}
	r->next = NULL;			//单链表收尾
}

//输出单链表
void DispList(LinkNode *L)
{
	LinkNode *p = L;
	while (p != NULL)
	{
		printf("%d ", p->data);
		p = p->next;
	}
	printf("\n");
} 

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/282671.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

windows go环境安装 swag

windows 下载依赖包 go get github.com/swaggo/swag/cmd/swag编译swag cd $GOPATH\pkg\mod\github.com\swaggo\swagv1.16.2\cmd\swagps: go env 获取 GOPATH位置 go installps: 此时 $GOPATH\bin下出现了 swag.exe 项目根目录下执行swag 初始化 swag init生成结果

vue中使用echarts实现省市地图绘制,根据数据显示省市天气图标及温度信息

一、实现效果 使用echarts实现省市地图绘制根据数据显示省下市的天气图标根据数据显示省下市的温度信息 二、实现方法 1、安装echarts插件 npm install echarts --save2、获取省市json数据 https://datav.aliyun.com/portal/school/atlas/area_selector 通过 阿里旗下的高…

如何用Python批量计算Word中的算式

一、问题的提出 到了期末&#xff0c;大家都在忙着写总结、改试卷、算工作量&#xff0c;写总结可以借助于ChatGPT&#xff0c;改试卷可以用星火的自动批阅功能&#xff0c;算工作量就是一项比较棘手的问题&#xff0c;因为它涉及很多算式&#xff0c;有时需要老师用计算器算来…

10TB海量JSON数据从OSS迁移至MaxCompute

前提条件 开通MaxCompute。 在DataWorks上完成创建业务流程&#xff0c;本例使用DataWorks简单模式。详情请参见创建业务流程。 将JSON文件重命名为后缀为.txt的文件&#xff0c;并上传至OSS。本文中OSS Bucket地域为华东2&#xff08;上海&#xff09;。示例文件如下。 {&qu…

每日一练(编程题-C/C++)

目录 CSDN每日一练1. 2023/2/27- 一维数组的最大子数组和(类型&#xff1a;数组 难度&#xff1a;中等)2. 2023/4/7 - 小艺照镜子(类型&#xff1a;字符串 难度&#xff1a;困难)3. 2023/4/14 - 最近的回文数(难度&#xff1a;中等)4. 2023/2/1-蛇形矩阵(难度&#xff1a;困难)…

算法基础之最短编辑距离

最短编辑距离 核心思想 &#xff1a; 线性dp 集合定义 &#xff1a; f[i][j]为操作方式的最小值 集合计算 : 三种操作 取最小 ① 删除 : 将a[i]删掉 使ab相同 –> f[i-1][j] 1 f[i][j]② 增添 : 在a[i]后加上一个数 使ab相同 –> f[i][j-1] 1 f[i][j]③ 替换 : 将a[…

基于ssm的航空票务推荐系统的设计与实现论文

摘 要 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xff0c;航班信息因为其管理内容繁杂&#xff0c;管理数量繁多导致手工进行处理不能满足广大…

基于Python的新闻爬取和推荐系统实践

基于Python的新闻爬取和推荐系统实践 项目概述数据集来源技术栈功能特点普通用户功能管理员功能需求 创新点 项目概述 在这个全功能的新闻爬取和推荐系统项目中&#xff0c;我们致力于构建一个高效、智能的平台&#xff0c;为用户提供个性化的新闻阅读体验。采用了Python语言&…

oracle执行不了update

oracle数据库select等其他语句执行正常&#xff0c;update语句执行后一直执行不完&#xff0c;原因是产生了记录锁。 &#xff08;1&#xff09;查询锁 SELECT a.sid, a.serial#,a.USERNAME,ao.OBJECT_NAME FROM v$locked_object lo, dba_objects ao, v$session a WHERE ao.o…

C语言易错知识点十(指针(the final))

❀❀❀ 文章由不准备秃的大伟原创 ❀❀❀ ♪♪♪ 若有转载&#xff0c;请联系博主哦~ ♪♪♪ ❤❤❤ 致力学好编程的宝藏博主&#xff0c;代码兴国&#xff01;❤❤❤ 许久不见&#xff0c;甚是想念&#xff0c;真的是时间时间&#xff0c;你慢些吧&#xff0c;不能再让头发变秃…

电子邮件地址填写指南:格式与常见问题解答

一个专业的电子邮件地址是一个你只用于工作目的的通信帐户。当你给收件人发送电子邮件时&#xff0c;这是他们最先看到的细节之一。无论你的职位或行业如何&#xff0c;拥有一个专业的电子邮件地址都可以提高你和所在公司的可信度。 在本文中我们解释了专业的电子邮件地址是什么…

PAT 乙级 1033 旧键盘打字

旧键盘上坏了几个键&#xff0c;于是在敲一段文字的时候&#xff0c;对应的字符就不会出现。现在给出应该输入的一段文字、以及坏掉的那些键&#xff0c;打出的结果文字会是怎样&#xff1f; 输入格式&#xff1a; 输入在 2 行中分别给出坏掉的那些键、以及应该输入的文字。其…

使用Vue3开发学生管理系统模板1

环境搭建 通过解压之前《Vue3开发后台管理系统模板》的代码&#xff0c;我们能够得到用户增删改查的页面&#xff0c;我们基于用户增删改查的页面做进一步的优化。 创建学生增删改查页面 第一步&#xff1a;复制用户增删改查页面&#xff0c;重命名为StudentCRUD.vue <…

java图书管理系统

主要模块&#xff1a; 为用户开通借书服务增加图书信息登记图书借出信息 技术栈&#xff1a; JSPServletTomcat9.0IDEAMysql 前台登录验证使用框架 数据库脚本包括登录用户名和密码已经写在了数据库脚本.sql 中 解压“需要的jar包”添加到项目的dependency中 运行效果&a…

构建基于小红书笔记详情API的内容生态

随着互联网的发展&#xff0c;内容生态的构建已经成为了许多企业和个人的重要任务。小红书作为一家以内容分享为主的社交平台&#xff0c;其API的开放为开发者提供了一种全新的方式来获取用户生成内容&#xff08;UGC&#xff09;。本文将介绍如何从无到有地构建基于小红书笔记…

告别HTTP,拥抱HTTPS!免费SSL证书领取指南

为什么选择HTTPS&#xff1f; HTTP和HTTPS之间的主要区别在于安全性。HTTP是一种不安全的协议&#xff0c;数据在传输过程中是明文的&#xff0c;容易受到中间人攻击。而HTTPS通过SSL&#xff08;Secure Sockets Layer&#xff09;或TLS&#xff08;Transport Layer Security&…

zabbix通过自动发现-配置监控项、触发器(小白教程)

自动发现配置参考链接&#xff08;不小白&#xff0c;不友好&#xff09; zabbix-get介绍 1配置 zabbix server&#xff1a;版本7&#xff08;不影响&#xff09;,IP地址&#xff1a;192.168.0.60zabbix agent&#xff1a;版本agent1&#xff08;不影响&#xff09;&#xff…

【Graylog】通过Pipelines在Graylog生成IP地理位置信息

序 在当今数字化时代&#xff0c;随着网络攻击的不断增加和全球化的用户活动&#xff0c;了解IP地址的地理位置信息变得越来越重要。对于网络安全和营销策略来说&#xff0c;掌握IP地址的地理信息可以带来许多好处。 接下里将介绍如何通过Graylog的Pipelines功能&#xff0c;…

arkts中@Watch监听的使用

概述 Watch用于监听状态变量的变化&#xff0c;当状态变量变化时&#xff0c;Watch的回调方法将被调用。Watch在ArkUI框架内部判断数值有无更新使用的是严格相等&#xff08;&#xff09;&#xff0c;遵循严格相等规范。当在严格相等为false的情况下&#xff0c;就会触发Watch的…

【数据结构——图】图的最短路径(头歌习题)【合集】

目录 第1关&#xff1a;单源最短路径完整代码 第2关&#xff1a;多源最短路径输入格式:输出格式:完整代码 第1关&#xff1a;单源最短路径 给一个n(1 ≤ n ≤ 2500) 个点 m(1 ≤ m ≤ 6200) 条边的无向图&#xff0c;求 s 到 t 的最短路。 输入格式: 第一行四个由空格隔开的整…