递增的整数序列链表的插入(不带头结点)

题目背景:
本题要求实现一个函数,在递增的整数序列链表(带头结点)中插入一个新整数,并保持该序列的有序性。

函数接口定义:
List Insert( List L, ElementType X );
其中List结构定义如下:

typedef struct Node PtrToNode;
struct Node {
ElementType Data; /
存储结点数据 /
PtrToNode Next; /
指向下一个结点的指针 /
};
typedef PtrToNode List; /
定义单链表类型 */
L是给定的带头结点的单链表,其结点存储的数据是递增有序的;函数Insert要将X插入L,并保持该序列的有序性,返回插入后的链表头指针。

裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>

typedef int ElementType;
typedef struct Node *PtrToNode;
struct Node {
ElementType Data;
PtrToNode Next;
};
typedef PtrToNode List;

List Read(); /* 细节在此不表 /
void Print( List L ); /
细节在此不表 */

List Insert( List L, ElementType X );

int main()
{
List L;
ElementType X;
L = Read();
scanf("%d", &X);
L = Insert(L, X);
Print(L);
return 0;
}

/* 你的代码将被嵌在这里 */
输入样例:
5
1 2 4 5 6
3
输出样例:
1 2 3 4 5 6

关于此题的解法我就不详细写了,写完了这题之后尝试写了一种不带头结点的解法,做此分享。
**对比一下两种做法,
不带头结点的List Read()Print():

List Read() 
{
	int n;
	List head,current, tmp;
	head=current=(PtrToNode)malloc(sizeof(struct Node));
	scanf_s("%d", &n);
	scanf_s("%d", &current->Data);
	current->Next = NULL;
	n--;
	//尾插法建立单链表
	while (n--) {
		tmp = (PtrToNode)malloc(sizeof(struct Node));
		tmp->Next = NULL;

		//输入结点data 数据域  尾插法
		scanf_s("%d", &tmp->Data);
		current->Next = tmp;
		current = tmp;
	}
	return head;
}
void Print(List L) 
{
	List tmp = L;
	while (tmp->Next != NULL) {
		printf("%d ", tmp->Data);
		tmp = tmp->Next;
		if (tmp->Next==NULL) //最后一个结点
		{
			printf("%d", tmp->Data);
		}
   }
	return 0;
	
}

带头结点的List Read()Print()

List Read()
{
    int n;
    List head, tmp, cur;
    head = cur = (List)malloc(sizeof(struct Node));
    cur->Next = NULL;
    scanf("%d", &n);
    while (n--)
    {
        tmp = (List)malloc(sizeof(struct Node));
        tmp->Next = NULL;
        scanf("%d", &tmp->Data);

        cur->Next = tmp;
        cur = tmp;
    }
    return head;
}
void Print(List L)
{
    List tmp = L;
    while (tmp->Next)
    {
        tmp = tmp->Next;
        printf("%d ", tmp->Data);

    }
    printf("\n");
}

其实刚开始的时候我不太明白这个List Read()带头结点和不带头结点的时候有什么不一样,仔细思考一下,带头结点的意思就是头结点之后的那个结点是一个数据结点,头结点的Data 未知,Next指向第一个数据结点,不带头结点就很简单,直接把头结点赋值为第一个数据结点存入相应的信息就可以了。
然后在Print()的时候,需要加一个判断语句;

if (tmp->Next==NULL) //最后一个结点
		{
			printf("%d", tmp->Data);
		}
   }

因为最后一个结点的Next是空的,无法进入循环表达式输出Data,所以要在上一句加如果最后一个结点的Next为NULL,则打印Data,这样就可以完整输出整个单链表了。

最后贴出此题的不带头结点的源码分享,带头结点的网上有很多解法我就不复述了。

#include<stdio.h>
#include<stdlib.h>
typedef int ElementType;
typedef struct Node* PtrToNode; //结构体类型的指针
struct Node {
	ElementType Data;
	PtrToNode Next;
};
typedef PtrToNode List; //定义单链表类型 PtrToNode (struct Node*)

//建立读入链表
List Read() 
{
	int n;
	List head,current, tmp;
	head=current=(PtrToNode)malloc(sizeof(struct Node));
	scanf_s("%d", &n);
	scanf_s("%d", &current->Data);
	current->Next = NULL;
	n--;
	//尾插法建立单链表
	while (n--) {
		tmp = (PtrToNode)malloc(sizeof(struct Node));
		tmp->Next = NULL;

		//输入结点data 数据域  尾插法
		scanf_s("%d", &tmp->Data);
		current->Next = tmp;
		current = tmp;
	}
	return head;
}
void Print(List L) 
{
	List tmp = L;
	while (tmp->Next != NULL) {
		printf("%d ", tmp->Data);
		tmp = tmp->Next;
		if (tmp->Next==NULL) //最后一个结点
		{
			printf("%d", tmp->Data);
		}
   }
	return 0;
	
}
List Insert(List L,ElementType k)
{
	List tmp;
	List head = L;
	tmp = (PtrToNode)malloc(sizeof(struct Node));
	tmp->Data = k;
	tmp->Next = NULL;

	while (L->Next && (L->Next->Data < k)) { 
		L = L->Next;
	}
	tmp->Next = L->Next;
	L->Next = tmp;

	return head;
}

int main() {
	ElementType k;
	List L;
	L=Read();
	scanf_s("%d", &k);
	L = Insert(L, k);
	Print(L);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值