链表排序(冒泡排序法
#include<iostream>
using namespace std;
struct Node
{
int num;//学号
int score;//成绩
Node* next;
};
void Creat(Node*& head, int, int,int);
void Show(Node* head);
void BubbleSort(Node*& head, int n);
int main()
{
int N, M;
while (cin >> N >> M)
{
int n = 0;
Node* head = new Node; //空的头节点
n = N + M; //n是总链表的数据个数
int num = 0, score = 0;//记录学号和成绩
Creat(head, num,score,n);
BubbleSort(head, n);
Show(head);
}
return 0;
}
//创建链表
void Creat(Node*& head, int num, int score,int n)
{
Node* p = head;
Node* s=new Node;
for (int i = 0; i < n; i++) //循环n次输入数据
{
cin >> num >> score;
s->num = num;
s->score = score;
p->next = s;
p = s;
s = new Node;
}
p->next = NULL;
delete s;
}
//遍历链表
void Show(Node* head)
{
head=head->next;//头指针无数据
while (head!=NULL)
{
cout << head->num << " " << head->score << endl;
head = head->next;
}
}
//数据排序,冒泡排序
void BubbleSort(Node*& head,int n)
{
//n记录链表结点的个数
Node* p, * q, * tail;//创建三个指针,进行冒泡排序
p = head;
for (int i = 1; i < n; i++)//外层循环,跟数组冒泡排序一样
{
q = head->next;//令q指向第一个结点
p = q->next;//令p指向后一个结点
tail =head;//让tail始终指向q前一个结点,方便交换,也方便与进行下一步操作
for (int j=0; j < n - i; j++) //内层循环 次数跟数组冒泡排序一样
{
if (q->num > p->num)//如果该结点的值大于后一个结点,则交换
{
q->next = p->next;
p->next = q;
tail->next = p;
}
tail = tail->next;
q = tail->next;
p = q->next;
}
}
}
链表头节点存储数据
需要改动相应的代码,运用一个辅助头节点help来实现
#include<iostream>
using namespace std;
struct Node
{
char data;
Node* next;
};
void Creat(Node*& head, char ch);
void Change(Node*&);
void Show(Node*);
int main()
{
char ch;
while (cin >> ch)
{
Node* head = NULL;
Creat(head, ch);
Node* help = new Node; //辅助头节点,因为创建时head中储存数据
help->next = head;
Change(help);
Show(help);//头节点变成了help
}
return 0;
}
void Creat(Node*& head, char ch)
{
Node* p = new Node;
Node* pre = head;
if (head == NULL)
{
head = p;
}
pre = p;
p->data = ch;
pre->next = p;
pre = p;
p = new Node;
ch = cin.get();
while (ch != '\n' && !cin.eof())
{
p->data = ch;
pre->next = p;
pre = p;
p = new Node;
ch = cin.get();
}
pre->next = NULL;
delete p;
}
void Show(Node* head)
{
head = head->next;
while (head!=NULL)
{
cout << head->data;
head = head->next;
}
cout << endl;
}
void Change(Node*&help)
{
Node* p, * r;
//辅助头节点help
p = help->next;
help->next = NULL;
while (p != NULL)
{
r = p->next;
p->next = help->next;
help->next = p;
p = r;
}
}
链表逆置
#include<iostream>
using namespace std;
struct Node
{
char data; //数据域
Node* next; //指针域
};
void Creat(Node*& head, char ch);
void Change(Node*& head);
void Show(Node* head);
int main()
{
char ch; //输入的字符
while (cin >> ch)
{
Node* head = new Node; //由于头指针(头指针)是链表的起始标记,所以为之开辟一个不储存数据的节点,仅用来标记链表
Creat(head, ch); //为输入的字符串创建链表
Change(head); //将链表反置
Show(head); //遍历链表,输出
delete head; //删除头指针(不考虑内存泄露)
}
return 0;
}
/* 创建链表函数
* 思路:利用中间指针p,pre链接前后的链表结点
*/
void Creat(Node*& head, char ch)
{
Node* p = new Node; //后一个指针(新结点)
Node* pre = head; //前一个指针(尾部结点),从头指针head开始
//使用do...while结构是为了后面的p->data = *ch服务的,因为*ch的第一个值已经在cin >> ch中给出了
do
{
p->data = ch; //为新节点的数据域赋值
pre->next = p; //让尾部结点的指针域指向新节点,链接前后结点
pre = p; //将前指针的位置移动到下一位
p = new Node; //将后指针的位置移动到另一个新节点
ch = cin.get(); //cin.get()会提取缓冲区的字符,包括换行符(这里不用<stdio.h>库中的gerchar())
} while (ch != '\n' && !cin.eof()); //这一步是为了判断字符串的结束,当遇到换行符或者无数据时结束
pre->next = NULL; //让链表的末尾结点的指针域为空指针,表示链表的结束
delete p; //删除在最后一次循环中创建出来的无用结点
return;
}
void Show(Node* head)
{
head = head->next; //由于头结点不包含数据,所以将头指针head移动到首结点处
while (head != NULL)
{
if (head->data != '\r') //跳过回车符
{
cout << head->data; //输出数据
}
head = head->next; //移动到下一结点
}
cout << endl;
return;
}
void Change(Node*& head)
{
Node* p, * r;
p = head->next; //将头结点与其余结点断开
head->next = NULL; //将头结点的指针域设为空指针
while (p != NULL)
{
r = p->next;
p->next = head->next;
head->next = p;
p = r;
}
return;
}