目录
顺序表是数据结构的一种,是List的子类,以数组的形式进行存储。
顺序表的特点:
- 顺序表都是连续的。
- 存取速度快,依靠下标直接进行存取。
- 不适合频繁插入和删除,需移动大量元素,时间复杂度高。
顺序表首先需要设置默认大小,以及所使用的容量,还需定义一个数组。
- public int[] elem;
- public int usedSize;//0
- //默认容量
- private static final int DEFAULT_SIZE = 10;
-
- public MyArrayList() {
- this.elem = new int[DEFAULT_SIZE];
- }
直接添加:需要判断是否容量已满需要扩容,再向数组已利用空间之后插入元素。
- /**
- * 判断当前的顺序表是不是满的!
- * @return true:满 false代表空
- */
- public boolean isFull() {
- if(usedSize==elem.length){
- return true;
- }
- return false;
- }
- /**
- * 扩容(实际上顺序表底层扩容为1.5倍)
- */
- public void reSize(){
- this.elem= Arrays.copyOf(elem,2*elem.length);
- }
- // 新增元素,默认在数组最后新增
- public void add(int data) {
- if(isFull()){
- reSize();
- }
- elem[usedSize]=data;
- usedSize++;
- }
指定位置添加:首先需要判断位置的合法性,然后再判断是否需要扩容,最后再逐步右移,在指定位置添加元素。
- // 在 pos 位置新增元素
- public void add(int pos, int data) {
- if(checkPosInAdd(pos)&&!isFull()){
- for(int j=usedSize-1;j>=pos;j--){
- elem[j+1]=elem[j];
- }
- elem[pos]=data;
- usedSize++;
- }
- }
删除第一次出现的关键字:先对数组中的元素进行遍历,找到待查找元素的下标,然后左移进行覆盖删除。
- /**
- * 删除第一次出现的关键字key
- * @param key
- */
- public void remove(int key) {
- boolean flag=false;
- for(int i=0;i<usedSize;i++){
- if(elem[i]==key){
- flag=true;
- for(int j=i;j<usedSize-1;j++){
- elem[j]=elem[j+1];
- }
- elem[usedSize-1]=0;
- usedSize--;
- break;
- }
- }
- if(flag==false){
- System.out.println("顺序表中没有此元素");
- }
-
- }
删除所有出现的关键字:利用双指针进行遍历,设置right和left指针,如果遍历到待删除的元素,则right++,否则left++,将right所指的元素赋值给left。
- /**
- * 删除顺序表中所有的key
- * @param val
- */
- public void removeAll(int val){
- int left=0;
- int right=0;
- while(right<usedSize){
- if(elem[right]==val){
- right++;
- }else{
- elem[left]=elem[right];
- left++;
- right++;
- }
- }
- usedSize=left;
- }
判断位置合法性,然后直接进行更新。
- // 获取 pos 位置的元素
- public int get(int pos) {
- if(checkPosInAdd(pos)&&pos!=usedSize){
- return elem[pos];
- }else{
- throw new PosException("位置不合法");
- }
- }
- // 给 pos 位置的元素设为更新为 value
- public void set(int pos, int value) {
- if(checkPosInAdd(pos)&&pos!=usedSize){
- elem[pos]=value;
- }
- }
- /**
- * 打印顺序表:
- * 根据usedSize判断即可
- */
- public void display() {
- for(int i=0;i<usedSize;i++){
- System.out.print(elem[i]+" ");
- }
- System.out.println();
- }
- // 判定是否包含某个元素
- public boolean contains(int toFind) {
- for(int i=0;i<usedSize;i++){
- if(elem[i]==toFind){
- return true;
- }
- }
- return false;
- }
- // 查找某个元素对应的位置
- public int indexOf(int toFind) {
- for(int i=0;i<usedSize;i++){
- if(elem[i]==toFind){
- return i;
- }
- }
- return -1;
- }
首先判断位置的合法性,再进行查找。
- // 获取 pos 位置的元素
- public int get(int pos) {
- if(checkPosInAdd(pos)&&pos!=usedSize){
- return elem[pos];
- }else{
- throw new PosException("位置不合法");
- }
- }
将数组中的元素全部置为0,便于回收,修改数组的当前使用长度为0。
- // 清空顺序表
- public void clear() {
- for (int i=0;i<usedSize;i++){
- elem[i]=0;
- }
- usedSize=0;
-
- }
利用二维数组的思想:定义一个泛型为顺序表的顺序表,将每一行的第一个元素和最后一个元素置为1,再利用杨辉三角的特点,当前元素的值=上一行这一列的元素+上一行前一列的元素,之后再将每一行都添加进去。
- public static List<List<Integer>> yangHuiTriangle(int n){
- List<List<Integer>> list = new ArrayList();
- List<Integer> row = new ArrayList();
- row.add(1);
- list.add(row);
- for(int i=1;i<n;i++){
- List<Integer> preRow = list.get(i-1);
- List<Integer> currentRow = new ArrayList();
- currentRow.add(1);
- for(int j=1;j<i;j++ ){
- Integer m=preRow.get(new Integer(j))+preRow.get(j-1);
- currentRow.add(m);
- }
- currentRow.add(1);
- list.add(currentRow);
- }
- return list;
- }
首先需要定义一个牌类,有花色和大小两个属性。
- public class Card {
- private char design;
- private int size;
-
- public Card(char design, int size) {
- this.design = design;
- this.size = size;
- }
-
- public char getDesign() {
- return design;
- }
-
- public void setDesign(char design) {
- this.design = design;
- }
-
- public int getSize() {
- return size;
- }
-
- public void setSize(int size) {
- this.size = size;
- }
-
- @Override
- public String toString() {
- return "{" + design +
- " " + size +
- '}';
- }
- }
定义一个指定泛型为Card牌类的顺序表,然后再将52张牌(大小王除外)添加进去。
- /**
- * 买牌
- * 将52张牌(除大小王)加入到集合中
- * J、Q、K用11、12、13替代
- * @return
- */
- public List<Card> buyCard(){
- char[] design={'♥','♦','♣','♠'};
- List<Card> list=new ArrayList<>();
- for(int i=0;i<4;i++){
- for(int j=0;j<13;j++){
- list.add(new Card(design[i],j));
- }
- }
- return list;
- }
将顺序表中存放的牌打乱:利用for循环,Random类生成一个随机数,然后与指定位置元素交换。
- /**
- * 洗牌:保证牌是乱序的
- */
- public List<Card> shuffle(List<Card> list){
- for(int i=list.size()-1;i>0;i--){
- Random random = new Random();
- int num=random.nextInt(i);
- swap(list,i,num);
- }
- return list;
- }
-
- /**
- * 将牌进行交换
- */
- private void swap(List<Card> list,int i,int j){
- Card card=list.get(i);
- list.set(i,list.get(j));
- list.set(j,card);
- }
假设有三个玩家,依次每人取五张牌:定义一个泛型为牌类顺序表的顺序表,每次从牌顺序表中移除牌向玩家顺序表中添加。
- /**
- * 发牌:三个人轮流连续发五张牌
- * @param list
- * @return
- */
- public List<List<Card>> deal(List
list){ - List<List<Card>> player =new ArrayList<>();
- List<Card> player1=new ArrayList<>();
- List<Card> player2=new ArrayList<>();
- List<Card> player3=new ArrayList<>();
- player.add(player1);
- player.add(player2);
- player.add(player3);
- for(int i=0;i<5;i++){
- for(int j=0;j<3;j++){
- Card card =list.remove(0);
- player.get(j).add(card);
- }
- }
- return player;
- }
- public class Test {
- public static void main(String[] args) {
- Game game = new Game();
- List<Card> list = game.buyCard();
- System.out.println(list);
- System.out.println("洗牌:");
- game.shuffle(list);
- System.out.println(list);
- List<List<Card>> player=game.deal(list);
- List<Card> player1=player.get(0);
- List<Card> player2=player.get(1);
- List<Card> player3=player.get(2);
- System.out.println("玩家1:"+player1);
- System.out.println("玩家2:"+player2);
- System.out.println("玩家3:"+player3);
-
- }
- }
运行结果: