首先由一道题引出:
结构与链表初步(指针+链表结构)
题目描述:
首先看看教材第十章第11例题如下:
在例题的基础上,做适当修改,建立一个具有n个节点(Node)的单向链表,每个节点包含一个整形数值和一个指向本节点类型后向指针,对该链表按照升序进行排序(定义一个排序函数,void sort(Student *),采用冒泡算法),输出排序的结果。(注意输入、输出格式!)
#include <iostream>
struct Student
{
long number;
float score;
Student* next;
};
Student* head;//链首指针
Student* Create()
{
Student* pS; //创建的结点指针
Student* pEnd; //链尾指针,用于在其后面插入结点
pS=new Student; //新建一个结点,准备插入链表
cin >>pS->number >>pS->score; //给结点赋值
head=NULL; //一开始链表为空
pEnd=pS;
while(pS->number!=0)
{
if(head==NULL)
head=pS;
else
pEnd->next=pS;
pEnd=pS; //s点
pS=new Student;
cin >>pS->number >>pS->score;
}
pEnd->next=NULL;
delete pS;
return(head);
}
void ShowList(Student* head)
{
cout <<"now the items of list are \n";
while(head)
{
cout <<head->number <<"," <<head->score <<endl;
head=head->next;
}
}
int main()
{
ShowList(Create());
}
输入
输入链表中各节点的整数值
输出
输出排序后链表中各节点的整数值
输入样例:
8
34 5 66 89 2 6 77 0
输出样例:
0 2 5 6 34 66 77 89
AC代码:
#include <iostream>
using namespace std;
struct student{
int num;
student*next;
};
student* create(int n)
{
student*head=new student;
student*pe;
student*ps=head;
for(int i=0;i<n;i++)
{
pe=new student;
cin>>pe->num;
pe->next=NULL;
ps->next=pe;
ps=pe;
}
return head;
}
void print(student*head)
{
for(student*p=head;p;p=p->next)
{
if(p!=head)
cout<<p->num<<" ";
}
}
void sort(student*head)
{
if(head==NULL||head->next==NULL)
{
return ;
}
student*newhead=head;
student*cur=head;
student*tail=NULL;
for(newhead;newhead->next!=NULL;newhead=newhead->next)
{
for(cur=head;cur->next!=tail;cur=cur->next)
{
int t;
if(cur->num>cur->next->num)
{
t=cur->num;
cur->num=cur->next->num;
cur->next->num=t;
}
}
tail=cur;
}
}
int main()
{
int n;
cin>>n;
student*head;
head=create(n);
sort(head);
print(head);
return 0;
}
首先,解读题意,这道题就是要我们根据一个给定的数据n,创建具有n个节点的链表
所以,我们需要首先创建链表,在这里我们使用尾插法创建单链表:
//创建单链表:
//首先,我们需要定义一个结构体类型为节点类型
typedef struct node{
int data;
node*next;
}node; //此处使用typedef来重命名结构体类型,使之简洁
//然后是创建链表的函数
node*create(int n)
{
node*head=new node;
node*pre=head;//前一个节点
node*p;//现在节点
for(int i=0;i<n;i++)
{
p=new node;//开辟新节点空间
cin>>p->data;//初始化新节点数据
p->next=NULL;//定义尾指针
pre->next=p;//构建前一节点和现在节点关系
pre=p;//迭代,现节点变为前一节点
}
return head;
}
以下是创建链表的思路图:
下面创建并初始化链表之后,我们需要知道如何遍历链表,掌握链表的输出:
void print(node* head)
{
//要打印节点数据,需要遍历节点
for(node*p=head->next;p;p=p->next)//p从1节点开始
//head->next指的就是1节点,最后执行完最后一个节点之后才到达p=NULL,从而停止执行
{
cout<<p->data<<" ";
}
}
此循环显示了链表如何遍历
接下来,就是链表的冒泡排序:
void sort(node* head)
{
node*cur;
node*tail=NULL;
for(node*p=head->next;p;p=p->next)//上层遍历链表,控制
{
for(cur=head->next;cur->next!=tail;cur=cur->next)
//下层遍历链表,尾指针需要更新,此为冒泡排序思想,已经排过的无需再排
{
if(cur->data>cur->next->data)//升序排列
{
int tmp;
tmp=cur->data;
cur->data=cur->next->data;
cur->next->data=tmp;
}
}
tail=cur;//更新尾指针
}
}
所以,实现链表冒泡排序的所有功能函数都已经写好了,接下来是总结代码:
#include <iostream>
using namespace std;
typedef struct node{
int data;
node*next;
}node;
node*create(int n)
{
node*head=new node;
node*pre=head;//前一个节点
node*p;//现在节点
for(int i=0;i<n;i++)
{
p=new node;//开辟新节点空间
cin>>p->data;//初始化新节点数据
p->next=NULL;//定义尾指针
pre->next=p;//构建前一节点和现在节点关系
pre=p;//迭代,现节点变为前一节点
}
return head;
}
void print(node* head)
{
//要打印节点数据,需要遍历节点
for(node*p=head->next;p;p=p->next)//p从1节点开始
//head->next指的就是1节点,最后执行完最后一个节点之后才到达p=NULL,从而停止执行
{
cout<<p->data<<" ";
}
}
void sort(node* head)
{
node*cur;
node*tail=NULL;
for(node*p=head->next;p;p=p->next)//上层遍历链表,控制
{
for(cur=head->next;cur->next!=tail;cur=cur->next)//下层遍历链表,尾指针需要更新,此为冒泡排序思想,已经排过的无需再排
{
if(cur->data>cur->next->data)//升序排列
{
int tmp;
tmp=cur->data;
cur->data=cur->next->data;
cur->next->data=tmp;
}
}
tail=cur;//更新尾指针
}
}
int main()
{
int n;
cin>>n;
node* head=create(n);
sort(head);
print(head);
return 0;
}