文章目录
- 前言
- 例题
- 题解
- 带头结点
- 不带头结点
前言
这个小例题涵盖的知识点还是非常多的。包括链表的定义,链表的尾插法,链表的遍历,冒泡排序用链表实现。链表可以使用带头结点和不带头结点的形式,各有千秋。
本文完整版使用带头结点的链表。
例题
下面这个是便于复制单独列一下。
样例输入
2 3
5 100
6 89
3 82
4 95
2 10
样例输出
2 10
3 82
4 95
5 100
6 89
题解
因为代码写了很多注释,这里就直接贴代码了.
自己写的时候有一些注意点如下:
1.定义结构体指针之后,如果不给已有结构体对象的地址,要使用malloc分配内存。
2.使用头结点作为链表的开头,头结点本身不存放数据。
3.插值以及遍历之后,对与头指针的位置,记得归位。
4.带头结点的链表更容易操作,理解起来没那么困难。
带头结点
#include<iostream>
using namespace std;
struct node{
int num;
int score;
struct node *nextNode;
};
void insertNodeAtTail(struct node* head,int num,int score)
{
//尾插法插入节点
struct node* newNode=(struct node*)malloc(sizeof(struct node));
newNode->num=num;
newNode->score=score;
newNode->nextNode=nullptr;
head->nextNode=newNode;
};
void merage(struct node* a,struct node* b)
{
//先找到a的最后一个节点
while(a->nextNode!=NULL){
a=a->nextNode;
}
//将a链表的最后一个节点与b链表头相连
a->nextNode=b->nextNode;
};
void sort_by_Num(struct node* a)
{
struct node *b;
//采用冒泡排序的方式
for(a=a->nextNode;a!=NULL;a=a->nextNode){
for(b=a->nextNode;b!=NULL;b=b->nextNode){
if(a->num > b->num){
int temp=a->num;
a->num=b->num;
b->num=temp;
int tempScore=a->score;
a->score=b->score;
b->score=tempScore;
}
}
//可以在这里排序完直接输出,也可以在main里面单独遍历
//cout<<a->num<<" "<<a->score<<endl;
}
}
int main () {
//两个链表的头结点,但不存放数据
node a,b;
int n,m,num,score;
cin>>n>>m;
node *head=&a;
node *headb=&b;
for(int i=0;i<n;i++){
cin>>num>>score;
insertNodeAtTail(head,num,score);
head=head->nextNode;
}
for(int i=0;i<m;i++){
cin>>num>>score;
insertNodeAtTail(headb,num,score);
headb=headb->nextNode;
}
merage(&a,&b);
sort_by_Num(&a);
//单独遍历输出的情况,需要让头指针指回头结点,因为上面尾插法
//改变了头指针位置
head=&a;
while(head->nextNode!=NULL){
head=head->nextNode;
cout<<head->num<<" "<<head->score<<endl;
}
return 0;
}
不带头结点
下面是不使用头结点的情况,即不单独用一个节点表示头结点,头结点本身存放数据。
我只写了插入数据的函数,其他两个函数都可以类比上面的写法。
#include<iostream>
using namespace std;
struct node{
int num;
int score;
struct node *nextNode;
};
void insertNodeAtTail(struct node* head,int num,int score)
{
//尾插法插入节点
struct node* newNode=(struct node*)malloc(sizeof(struct node));
newNode->num=num;
newNode->score=score;
newNode->nextNode=nullptr;
head->nextNode=newNode;
};
int main () {
//两个链表的第一个节点,要存数据的头结点
node a,b;
int n,m,num,score;
cin>>n>>m;
//两个链表头指针
node *headA=&a;
node *headB=&b;
for(int i=0;i<n;i++){
cin>>num>>score;
if(i==0)
{
//如果头结点,直接赋值
a.num=num;
a.score=score;
}
else
{
//不是头结点就尾插法
insertNodeAtTail(headA,num,score);
headA=headA->nextNode;
}
}
for(int i=0;i<m;i++){
cin>>num>>score;
if(i==0)
{
b.num=num;
b.score=score;
}
else
{
insertNodeAtTail(headB,num,score);
headB=headB->nextNode;
}
}
headA=&a;
for(int i=0;i<n;i++){
cout<<headA->num<<endl;
headA=headA->nextNode;
}
headB=&b;
for(int i=0;i<m;i++){
if(i!=m-1)
cout<<headB->num<<endl;
else
cout<<headB->num;
headB=headB->nextNode;
}
return 0;
}