链表由于和指针密切相关,不免会出现各种关于指针方面的问题,处理不当就会导致bug众多,可能是找不到该指针,可能是数据被覆盖……因此在写程序的开头,就需要先定好实现的大体方法,通过图的方式先把算法描述一遍再开始写程序。
一、关于c和c++的使用问题:
如果准备用C写,就尽量避免使用C++封装的部分,如果准备用C++写,就尽量少用malloc、free等表达形式
如链表中,申请新的内存空间时用list l1=(list)malloc(sizeof(struct element))的形式,如果list中有string类型的变量 在cin时候会报错,因为C无法明确知道string的大小,因此开辟内存空间的时候会出现Bug。
二、关于排序的问题:
对于链表的排序涉及到了两个结构的交换。
1.若采用交换指针的方式,则该名称指代的地址不变,位置发生改变。即:
这种情况下tail位于head前面,因此无法进行排序算法的实现。
2.可以采取交换数据的方式,但是如果进行大数据量的结构交换,则该方法过于繁杂。
3.查找该节点的前一个节点可以写一个previous函数,通过函数调用查找该节点,还可以使用双向链表进行查找。
4.链表中实现选择排序的一个较好办法是构造一个新链表,将已排序内容放入新的链表,最后再将新链表的表头放入原始链表,通过这种方法实现排序。
下面为使用链表的图书管理系统的源代码:
#include<stdlib.h>
#include<iostream>
#include<string>
using namespace std;
typedef struct element* list;
typedef struct element* position;
struct element{
string ID;
string NAME;
float price;
struct element* Next;
};
void input(list List){ //输入数据
while(1){
position temp;
temp=new element();
cin>>temp->ID;
if(temp->ID=="finish")break; //当遇到finish结束
cin>>temp->NAME;
cin>>temp->price;
position p=List;
while(p->Next!=NULL){
p=p->Next;
}
temp->Next=NULL;
p->Next=temp;
}
}
void output(list l){ //输出数据
position p;
p=l->Next;
if(p==NULL)cout<<"无法查到数据!"<<endl;
while(p!=NULL){
cout<<p->ID<<" "<<p->NAME<<" "<<p->price<<endl;
p=p->Next;
}
}
position previous(list l1,position p){ //查找前一个位置
position temp=new element();
temp=l1;
while(temp->Next!=p){
temp=temp->Next;
}
return temp;
}
void find_name(string NAME,list l){ //根据名称查找
position p;
p=l->Next;
while(p!=NULL){
if(p->NAME==NAME){
cout<<p->ID<<" "<<p->NAME<<" "<<p->price<<endl;
}
p=p->Next;
}
}
position find_id(string ID,list l){ //根据ID查找
position p;
p=l->Next;
while(p->ID!=ID&&p!=NULL){
p=p->Next;
}
if(p==NULL)printf("查找错误!\n");
else cout<<p->ID<<" "<<p->NAME<<" "<<p->price<<endl;
return p;
}
position mid(list l1,position head,position tail){ //快排的具体实现步骤
position Flag=l1->Next;
float flag=head->price;
position p=new element();
p->ID=head->ID;
p->NAME=head->NAME;
p->price=head->price;
while(head!=tail){
position temp=new element();
while(head!=tail&&tail->price<=flag){
tail=previous(l1,tail);
}
head->NAME=tail->NAME;
head->ID=tail->ID;
head->price=tail->price;
while(head!=tail&&head->price>=flag){
head=head->Next;
}
tail->ID=head->ID;
tail->NAME=head->NAME;
tail->price=head->price;
}
head->ID=p->ID;
head->NAME=p->NAME;
head->price=p->price;
while(Flag->ID!=p->ID){
Flag=Flag->Next;
}
return Flag;
}
void quick_sort(list l1,position head,position tail){ //快排的递归过程
if(head!=tail){
position middle=mid(l1,head,tail);
quick_sort(l1,head,previous(l1,middle));
quick_sort(l1,middle->Next,tail);
}
}
list select_sort(list l1){ //选择排序
list l2=(list)malloc(sizeof(struct element)); //排序链表的头指针
position Tail; //排序链表的尾指针
position p;//用于比较的指针
position pre;//最大节点的前一节点
position max;//指向最大的节点
l2->Next=NULL;
while(l1->Next!=NULL){
for(p=l1->Next,max=l1->Next;p!=NULL;p=p->Next){ //挑选最大节点
if(p->price>max->price){
max=p;
pre=previous(l1,p);
}
}
if(l2->Next==NULL){ //将最大节点放入新链表末尾
l2->Next=max;
Tail=max;
}
else {
Tail->Next=max;
Tail=max;
}
if(max==l1->Next){ //在原链表中去掉该节点
l1->Next=l1->Next->Next;
}
else {
pre->Next=max->Next;
}
if(l2->Next!=NULL){
Tail->Next=NULL; //新链表末尾置空
}
}
l1=l2;
return l1;
}
int main(){
list l1;
l1 = new element(); //此处不能用(list)malloc(sizeof(struct element));否则使用string时会报错
l1->Next=NULL;
while(1){
printf("--------------菜单-----------------\n");
printf("--------1.输入图书信息-------------\n");
printf("--------2.输出图书信息-------------\n");
printf("--------3.查找图书信息-------------\n");
printf("--------4.对图书信息进行排序-------\n");
printf("--------5.退出系统-----------------\n");
int c;
cin>>c;
switch(c){
case 1:
{
cout<<"请输入数据,并以finish表示结束。输入格式为:ISBN 名称 价格 "<<endl;
input(l1);
}break;
case 2:
output(l1);
break;
case 3:
{
cout<<"按ID查找请按1,按书名查找请按2:"<<endl;
int x;
cin>>x;
if(x==1)
{
printf("请输入该书的ID号:");
string id;
cin>>id;
find_id(id,l1);
}
else if(x==2){
printf("请输入该书的书名:");
string name;
cin>>name;
find_name(name,l1);
}
else {
cout<<"输入错误!"<<endl;
}
}
break;
case 4:
{
cout<<"采用快速排序请按1,采用选择排序请按2"<<endl;
int y;
cin>>y;
if(y==1){
position head=l1->Next;
position tail=l1->Next;
while(tail->Next!=NULL)
tail=tail->Next;
quick_sort(l1,head,tail);
}
else if(y==2){
l1=select_sort(l1);
}
else {
cout<<"输入错误!"<<endl;
}
}
break;
case 5:
exit(0);
break;
}
}
}