顺序表:
0.头文件
using namespace std;
#include
#include
#include
1.结点类和顺序表类:
vector的好处就是析构函数只要:s.clear();
//结点类
struct Student
{
int score;
string name;
};
//顺序表类
class Seqlist
{
public:
Seqlist(); //构造函数
~Seqlist() {s.clear();} //析构函数
int size(); //返回元素个数
void Traverse(); //遍历函数
void QuickSort(int i,int j); //快排的递归调用
int Partition(int i, int j); //快排的一次划分算法
void BiSearch(); //折半插入排序
private:
vector s;
int length;
};
2.构造函数
//构造函数
Seqlist::Seqlist()
{
Student m;
cout << "输入的学生成绩个数";
cin >> length;//length 即为最大容量
for (int i = 0; i < length; i++)
{
cout << "输入第" << i + 1 << "位学生姓名: ";
cin >> m.name;
cout << "输入" << i + 1 << "位学生成绩: ";
cin >> m.score; cout << endl;
s.push_back(m);
}
}
3.求表长,遍历函数
//返回元素个数
int Seqlist::size()
{
return s.size();
}
//遍历函数
void Seqlist::Traverse()
{
for (int i = 0; i < s.size(); i++)//修改前:i
*4.快排
①
temp指第一个元素,用来存放标记值;
i是0,表示表第一个元素;
j是length()-1,表示最后一个元素.
②
递归要避开枢轴,否则会溢出栈
③之前的bug:如int temp = s[i].score;改变了成绩的次序,未改变学生的次序
//快排的一次划分算法
int Seqlist::Partition(int i, int j)
{
Student temp = s[i]; //将首元素的key设为关键字
while (i= temp.score)
{
j--; //j一直循环到一个小于temp的值
}
if (i
*5 折半查找
//折半查找算法
void Seqlist::BiSearch()
{
int low = 0;
int high = s.size() - 1;
int find = 0;
int mid;
Student m;
cout << "输入新同学姓名";
cin >> m.name;
cout << "输入新同学成绩";
cin >> m.score;
if(m.score>s[s.size()-1].score) //m.score大于最大的,直接尾部加入
{
s.push_back(m);//如果不是vector,而是数组,此处应该有length++;下面一样.
}
else if(m.score s[mid].score)
{
low = mid + 1;
if (low == mid)
{
s.insert(s.begin() + mid , m);
}
find = 1; //终止循环
}
else //插入值与数组某元素相等
{
find = 1; //终止循环
s.insert(s.begin() + mid, m);
}
}
}
}
6.main()函数
int main()
{
Seqlist s1;
s1.Traverse();
//顺序表快排测试
s1.QuickSort(0, s1.size() - 1);
cout << "快速排序后"<
链式存储的排序算法:
0.头文件
using namespace std;
#include
#include
1.节点类和链表类:
为了在main()传参调用快速排序算法,不得不把Student *elem 改为public.
//结点类
struct Student
{
int score;
Student *next=nullptr; //结点类的*next 需要初始化,否则显示"读取访问权限冲突"
};
//链表类
class Linklist
{
public:
Linklist(); //构造函数
~Linklist(); //析构函数
void CreateLinklist(); //创建链表
int size(); //返回元素个数
void Traverse(); //遍历函数
Student *Partition(Student *pBegin, Student *pEnd); //快排的一次划分算法
void QuickSort(Student *pBegin, Student *pEnd); //快排的递归调用
void BiSearch(); //折半插入排序
Student *elem;
};
2.构造函数与析构函数
①elem new出头结点后,不需要为其数据域赋初值,只要将next指针域置nullptr即可
//构造函数
Linklist::Linklist()
{
elem = new Student;
elem->next = nullptr; //常量NULL实际上是数字0,可能引起误用.作为解决方案,nullptr是代表空指针的字面值常量
}
//析构函数
Linklist::~Linklist()
{
Student *p = elem;
while (p)
{
Student *q = p;
p = p->next;
delete q;
}
elem = nullptr;
//头删法
}
3.创建链表
也可以写成带参构造函数.
//创建链表
void Linklist::CreateLinklist()
{
Student *p, *q;
p = elem;
int n;
cout << "输入学生个数\n";
cin >> n;
for (int i = 0; i < n; i++)
{
q = new Student;
cout << "输入" << i + 1 << "位学生成绩: ";
cin >> q->score;cout << endl;
p->next = nullptr;
p->next = q;
p = p->next;
}
cout << "输入成功!\n";
}
4.表长和遍历
//学生个数
int Linklist::size()
{
int i = 0;
Student *p = elem->next; //p指向首元结点
while (p)
{
p = p->next;
i++;
}
return i;
}
//遍历函数
void Linklist::Traverse()
{
Student *q = elem->next; //首元结点
for (int i = 0; i < this->size(); i++)
{
cout << "第" << i + 1 << "位学生成绩:" << q->score << endl;
q = q->next;
}
}
*5链表类型的快排算法
①i指针之前的值都小于标记值
i~j之间的值都大于标记值
j之后的值都未判断大小,当j==nullptr,意味着一次排序结束.
②※递归算法QuickSort(Student *pBegin, Student *pEnd) 中,
注意if()内的第一行,输入的
Partition(Student *pBegin, Student *pEnd)
形参来自于
QuickSort(Student *pBegin, Student *pEnd)
的形参,
究其根本,是由
main()中(a1.elem->next, nullptr)传递实参.
//快排的一次划分算法(两个指针均向后移动)
Student* Linklist::Partition(Student *pBegin, Student *pEnd)//pBegin的实参是elem,pEnd的实参是最末元素的next,也就是nullptr
{
Student *i = pBegin; //首元结点
Student *j = i->next;
int flag = pBegin->score; //基准数字
while (j != pEnd) //循环到j是最后一个元素的next域(NULL状态)
{
if (j->score < flag)
{
i = i->next;
swap(i->score, j->score);
}
j = j->next;
}
swap(i->score, pBegin->score);
return i;
}
//快排的递归
void Linklist::QuickSort(Student *pBegin, Student *pEnd)
{
if (pBegin!=pEnd)
{
Student *pivot = Partition(pBegin,pEnd); //此处输入的是形参
QuickSort(pBegin, pivot);
QuickSort(pivot->next, pEnd);
}
}
6.main()
int main()
{
Linklist a1;
a1.CreateLinklist();
//返回学生数
cout << "学生有" << a1.size() << "位\n";
//遍历
a1.Traverse(); cout << endl;
//快排
a1.QuickSort(a1.elem->next, nullptr);
cout << "快排后:\n";
a1.Traverse();
system("pause");
return 0;
}
7.Bug
void Linklist::text()
{
Student *p = elem->next;
p->score = 100;
Traverse();
}
错误,不能直接修改结点的值