链式基数排序
说明:
适用于棋牌游戏发牌之后的排序,数量在十几到二十几之间
思路:
服务端发的牌是无序的,我们需要将牌按照花色和点数排列
- 按照点数创建9个单链表(对应麻将中一万到九万,一饼到九饼,一条到九条),将服务器发下的牌按照点数分别放进这9个单链表中,再将这9个单链表连接成1个单链表
- 按照花色创建3个单链表(对应麻将中饼子,万字,条子),将2处理好的链表按照花色分别放进这3个单链表中,再讲这3个单链表链接成一个单链表
代码:
public class Mahjong {
private int rank;//点数
private int suit;//花色
public Mahjong(int suit, int rank) {
this.rank = rank;
this.suit = suit;
}
public int getRank() {
return rank;
}
public void setRank(int rank) {
this.rank = rank;
}
public int getSuit() {
return suit;
}
public void setSuit(int suit) {
this.suit = suit;
}
@Override
public String toString() {
return "suit: "+this.suit+" rank: "+this.rank;
}
}
import org.junit.Test;
import java.util.LinkedList;
public class RadixSort {
public void radixSort(LinkedList list){
LinkedList[] rankList = new LinkedList[9];
for (int i = 0; i < 9; i++) {
rankList[i] = new LinkedList<>();
}
while (list.size()!=0){
Mahjong m = list.remove();
rankList[m.getRank()-1].add(m);
}
for (LinkedList mahjongs : rankList) {
list.addAll(mahjongs);
}
LinkedList[] suitList = new LinkedList[3];
for (int i = 0; i < 3; i++) {
suitList[i] = new LinkedList<>();
}
while(list.size()!=0){
Mahjong m = list.remove();
suitList[m.getSuit()-1].add(m);
}
for (LinkedList mahjongs : suitList) {
list.addAll(mahjongs);
}
}
@Test
public void test(){
LinkedList list=new LinkedList();
list.add(new Mahjong(3,1));
list.add(new Mahjong(2,3));
list.add(new Mahjong(3,7));
list.add(new Mahjong(1,1));
list.add(new Mahjong(3,8));
list.add(new Mahjong(2,2));
list.add(new Mahjong(3,2));
list.add(new Mahjong(1,3));
list.add(new Mahjong(3,9));
System.out.println(list);
radixSort(list);
System.out.println(list);
}
}
链表:
特点:
查询比较慢,需要逐个结点去遍历,添加和删除比较快,只需要改变前驱和后继的索引不需要去移动其他节点
单链表
特点:
除尾结点(最后一个结点)外,每个节点都有后继节点
/**
* 单链表
*/
public class SingleLinkList {
class Node {
E element;
Node next;
public Node(E element, Node next) {
this.element = element;
this.next = next;
}
}
Node first;
Node last;
int size;
/**
* 尾部添加
*
* @param e
*/
public void add(E e) {
Node node = new Node<>(e, null);
if (last == null) {
first = node;
last = node;
} else {
Node l = last;
l.next = node;
last = node;
}
size++;
}
/**
* 获取index位置的结点的值
*
* @param index
* @return
*/
public E get(int index) {
if (node(index) != null) {
return node(index).element;
} else {
return null;
}
}
/**
* 获取index位置结点
*
* @param index
* @return
*/
private Node node(int index) {
if (index < 0 || index > size - 1) {
return null;
} else {
Node node = first;
for (int i = 0; i < index; i++) {
node = node.next;
}
return node;
}
}
public void add(int index, E e) {
if (index < 0||index>size) {
return;
} else {
Node target = node(index);
Node node = new Node<>(e, target);
if (target == null) {
last = node;
}
Node pre = node(index - 1);
if (pre != null) {
pre.next = node;
} else {
first = node;
}
size++;
}
}
public void remove(){
Node pre = node(size-1);
if (pre!=null){
pre.next = null;
last = pre;
size--;
}else {
first = null;
last = null;
}
}
public void remove(int index){
if (index<0||index>size-1){
return;
}else {
Node target = node(index);
Node next = target.next;
target.next = null;
Node pre = node(index-1);
if (pre!=null){
pre.next=next;
}else {
first = next;
}
size--;
}
}
}
双向链表
特点:
除头结点(第一个结点)外,每个节点都有前驱结点,除尾结点(最后一个结点)外,每个节点都有后继节
点.相比于单链表,双链表可以从后往前遍历,查找速度要快
/**
* 双向链表类
* @param
*/
public class LinkedList {
/**
* 节点类
* @param
*/
class Node {
Node pre;
E element;
Node next;
public Node(Node pre, E element, Node next) {
this.pre = pre;
this.element = element;
this.next = next;
}
}
Node first;//头结点
Node last;//尾节点
int size;//大小
/**
* 尾部添加结点
* @param e
*/
public void add (E e){
Node node = new Node<>(last,e,null);
linkLast(node);
}
private void linkLast(Node node) {
if (last==null){
first = node;
}else {
Node l = last;
l.next = node;
}
last = node;
size++;
}
public E get (int index){
if (node(index)!=null){
return node(index).element;
}
return null;
}
/**
* 查找对应位置的结点
* @param index
* @return
*/
public Node node(int index){
if (index<0||index>size-1){
return null;
}else {
if (index node = first;
for (int i = 0; i < index; i++) {
node = node.next;
}
return node;
}else {
Node node = last;
for (int i = size; i > index; i--) {
node = node.pre;
return node;
}
}
}
return null;
}
public void add(int index,E e){
if (index<0){
return;
}else if (index>size){
index = size+1;
}
Node next = node(index);
Node pre = null;
if (next!=null){
pre = next.pre;
}else {
pre = last;
}
Node node = new Node<>(pre,e,next);
if (pre!=null){
pre.next = node;
}else {
first = node;
}
if (next!=null){
next.pre = node;
}else {
last = node;
}
size++;
}
/**
* 移除尾节点
*/
public void remove(){
if (size==0){
return;
}else {
Node pre = last.pre;
Node l = last;
if (pre!=null){
pre.next = null;
l.pre = null;
last = pre;
}else {
first = null;
last = null;
}
}
size--;
}
/**
* 移除index位置的结点
* @param index
*/
public void remove(int index){
if (index<0||index>size-1){
return;
}else {
Node target = node(index);
Node pre = target.pre;
Node next = target.next;
if (pre!=null){
pre.next = next;
}else {
first = next;
}
target.next = null;
target.pre = null;
if (next!=null){
next.pre = pre;
}else {
last = pre;
}
}
size--;
}
}