1.冒泡排序
(1)顺序结构实现(数组)
编程时的思路:
1.比较第一个和第二个元素,若第一个元素大于第二个元素,两个元素交换。
2.比较第二个和第三个元素,若第二个元素大于第三个元素,两个元素交换。
…
3.比较倒数第二个和最后一个元素,若倒数第二个元素大于最后一个元素,两个元素交换。
以上就可以写成一个循环,结果就是把数组最大的那个元素放到了最后的位置。
4.然后就要除去放了最大元素的位置,进行下一次循环,找出剩下的元素中最大的元素。
5.多次循环,不断找出最大的元素,当剩下的元素只有一个时,程序结束。
以上就可以写成一个嵌套循环,每一次内循环结束,外循环都让内循环的末尾位置(挡板)往前移动一个位置。
代码:
public static void bubbleSort(int[] arr) {
int i=arr.length;
while(i>0) { //外循环实现一个挡板,每一次内循环结束,i-1。
for(int j=0;j<i-1;j++) { //随着i不断减1,这个循环会一次次地找到剩下元素的最大元素
int temp;
if(arr[j]>arr[j+1]) {
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
i--;
}
}
(2)链式结构实现(链表)
编程时的思路:
大体上和顺序结构的差不多,都是用嵌套循环。
关键是实现末尾位置前移(挡板前移),这个需要设置多一个节点。
首先设置p为head节点,开始遍历链表,当完成一次循环之后,此时p就是倒数第二个位置的节点,要向让挡板前移,开始第二轮循环,就要设置一个节点q,让q得到p此时的位置。实现挡板的前移。
代码:
public class TestDemo {
public static void main(String[] args) {
int[] arr={23,85,67,134,7,99};
linklist list = new linklist();
for(int i=0;i<arr.length;i++) {
list.bulidlinklist(arr[i]);
}
list.sort();
list.printlist();
}
}
//链表的节点类
class Node2{
int data;
Node2 next;
Node2(int data){
this.data=data;
this.next=null;
}
}
//链表类
class linklist{
Node2 head;
void bulidlinklist(int data){
Node2 n = new Node2(data);
if(head==null) {
head=n;
}else {
n.next=head;
head=n;
}
}
void printlist() {
Node2 p=head;
while(p!=null) {
System.out.print(p.data+" " );
p=p.next;
}
}
//冒泡排序算法
void sort() {
Node2 p=head; //p是用于遍历链表的
Node2 q=null; //q是用于实现挡板前移的
while(p!=q) { //外循环,q在不断向前移动中,当p等于q,说明链表只有一个节点了,排序完成结束
while(p.next!=q) {
int temp;
if(p.data>p.next.data) {
temp=p.data;
p.data=p.next.data;
p.next.data=temp;
}
p=p.next;
}
q=p; //在p不断等于p.next中,当完成了一次循环,p就是挡板前的那部分链表的倒数第二个节点,此时让q=p,刚好实现挡板前移的效果
p=head; //重置p,开始新的一轮循环遍历
}
}
}
2.选择排序
(1)顺序结构实现(数组)
编程时的思路:
1.定义一个最小值变量smallest=数组的一个元素,让其分别和数组的每一个元素对比大小,如果smallest大于这个元素,则让更新smallest为这个元素,同时用flag记录这个元素在数组中的索引。
以上可以用一个循环遍历找出未实现排序的数组部分的最小值。
2.找出这些元素的最小值后,让该最小值的元素更改为:该未实现排序的数组部分的第一个元素,接着让该未实现排序的数组部分的第一个元素更改为smallest,实现数据的交换。
3.此时已经排好了一个元素,让挡板右移,对未实现排序的数组部分继续实行上述操作。
以上就可以写成一个嵌套循环,直到未实现排序的数组部分只剩下一个元素,程序结束。
代码:
public static void sellctionSort(int[] arr) {
int n=0;
while(n<arr.length-1 ) { //实现挡板右移,区分开未实现排序的数组部分和已经实现排序的数组部分
int smallest=arr[n]; //让smallest暂时等于未实现排序的数组部分的首元素
int flag=0;
for(int i=n;i<arr.length;i++) {
if(smallest>arr[i]) {
smallest=arr[i];
flag=i; //记录未实现排序的数组部分的最小元素的索引,便于交换数据
}
}
if(flag!=0) { //当flag是0,说明smallest暂时等于未实现排序的数组部分的首元素,刚刚好就是未实现排序的数组部分的首元素的最小元素,不用交换。
arr[flag]=arr[n];
arr[n]=smallest;
}
n++;
}
}
(2)链式结构实现(链表)
编程思路:
跟顺序结果没有什么差别,主要是交换节点过于麻烦,直接交换数据就可以了。
交换数据时,不能用flag记录索引,要再循环一次,找出最小值元素用于交换,以为没有链表没有索引可以直接找到
代码:
public class TestLinklist {
public static void main(String[] args) {
int[] arr= {12,53,13,65,24};
Singlelist list = new Singlelist(arr);
list.printlist();
System.out.println();
list.selectionsort();
list.printlist();
}
}
class Node1{
int data;
Node1 next;
Node1(int data){
this.data=data;
this.next =null;
}
}
class Singlelist{
Node1 head;
Singlelist(int data[]){
for(int i=0;i<data.length;i++) {
if(head==null) {
head=new Node1(data[i]);
}else {
Node1 p = new Node1(data[i]);
p.next=head;
head=p;
}
}
}
void printlist() {
Node1 p =this.head;
while(p!=null) {
System.out.print(p.data+" ");
p=p.next;
}
}
void selectionsort() {
// Node1 p = head;
// Node1 smallest = p;
// //此时head,p,smallest三个地址是一样的,都是head,名称不同而已
Node1 r=head;
while(r.next!=null) { //实现挡板右移
Node1 p =r;
int smallest= p.data;
while(p.next!=null) { //找出找出未实现排序的数组部分的最小值
if(smallest>p.next.data) {
smallest = p.next.data;
}
p=p.next;
}
Node1 q = r;
while(q!=null) { //再循环一次,找出最小值元素用于交换,以为没有链表没有索引可以接着找到
if(q.data==smallest) {
q.data=r.data;
break;
}
q=q.next;
}
r.data=smallest;
r=r.next;
}
}
}