数据结构之线性表

来源:互联网 发布:真正的粉丝就算 知乎 编辑:程序博客网 时间:2024/06/03 21:14

转载自:http://blog.csdn.net/luoweifu/article/details/8505178

线性表概述

线性表是最基本、最简单、也是最常用的一种数据结构。在线性表中数据元素之间的关系是线性,数据元素可以看成是排列在一条线上或一个环上。

线性表分为静态线性表和动态线性表,常见的有顺序表(静态的)、单向链表(动态的)和双向链表(动态的)。

线性表的操作主要包括:

1)计算表的长度n

(2)线性表是否为空

3)将元素添加到线性表的末尾

4)获取第i个元素,0≤i < n

5清除线性表

(6)返回列表中首次出现指定元素的索引,如果列表不包含此元素,则返回 -1。

(7)返回列表中最后一次出现指定元素的索引,如果列表不包含此元素,则返回 -1。

8)将新元素插入第i个位置,0≤i < n,使原来的第ii+1n–1个元素变为第i+1i+2n个元素。

(9)更改第i个元素

10)删除第i个元素,0≤i < n,使原来的第i+1i+2n–1个元素变为第ii+1n–2个元素

由此,对线性表抽象数据类型定义List接口如下:

List接口

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. package list;  
  2.   
  3. public interface List {  
  4.     /** 
  5.      * 将元素添加到线性表的末尾 
  6.      */  
  7.     public void add(Object e);  
  8.       
  9.     /** 
  10.      * 清除线性表 
  11.      */  
  12.     public void clear();  
  13.     /** 
  14.      * 获取i位置的元素 
  15.      * @param i 
  16.      * @return 
  17.      */  
  18.     public Object get(int i);  
  19.     /** 
  20.      * 返回列表中首次出现指定元素的索引,如果列表不包含此元素,则返回 -1。 
  21.      * @param e 
  22.      * @return 
  23.      */  
  24.     public int indexOf(Object e);  
  25.     /** 
  26.      * 在i后面插入一个元素e 
  27.      * @param i 
  28.      * @param e 
  29.      */  
  30.     public void insert(int i, Object e);  
  31.     /** 
  32.      * 判断线性表是否为空 
  33.      * @return 
  34.      */  
  35.     public boolean isEmpty();  
  36.     /** 
  37.      * 回列表中最后出现指定元素的索引,如果列表不包含此元素,则返回 -1。 
  38.      * @param e 
  39.      * @return 
  40.      */  
  41.     public int lastIndexOf(Object e);  
  42.     /** 
  43.      *  移除列表中指定位置的元素 
  44.      * @param i 
  45.      */  
  46.     public void remove(int i);  
  47.     /** 
  48.      * 用指定元素替换列表中指定位置的元素(可选操作)。 
  49.      * @param i 
  50.      * @param e 
  51.      */  
  52.     public void set(int i, Object e);  
  53.     /** 
  54.      * 返回线性表的大小 
  55.      * @return 
  56.      */  
  57.     public int size();  
  58. }  


顺序表

结构模型


图顺序存储结构内存结构示意图 


源代码

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. package list;  
  2.   
  3. public class ArrayList implements List{  
  4.     /** 
  5.      * 顺序表默认的初始大小 
  6.      */  
  7.     public static final int defLen = 10;  
  8.     private int maxLen;  
  9.     private Object[] array;  
  10.     private int size;  
  11.       
  12.     public ArrayList() {  
  13.         size = 0;  
  14.         maxLen = defLen;  
  15.         array = new Object[defLen];  
  16.     }  
  17.       
  18.     @Override  
  19.     public void clear() {  
  20.         size = 0;  
  21.     }  
  22.   
  23.     @Override  
  24.     public Object get(int i) {  
  25.         if(i>=0 && i<size)  
  26.             return array[i];  
  27.         else  
  28.             return null;  
  29.     }  
  30.   
  31.     @Override  
  32.     public int indexOf(Object e) {  
  33.         int i =0;   
  34.         while(i<size && !array[i].equals(e)) {  
  35.             i++;  
  36.         }  
  37.         if(i < size)  
  38.             return i;  
  39.         else  
  40.             return -1;  
  41.     }  
  42.   
  43.     @Override  
  44.     public void insert(int i, Object e) {  
  45.         if(i >= size) {  
  46.             i = size;  
  47.             if((size) >= maxLen)//如果插入数的位置大于顺序表的最大容量,则扩大容量  
  48.                 expand();  
  49.         }  
  50.         for(int j = size; j>i+1; j--) {  
  51.             array[j] = array[j-1];  
  52.         }  
  53.         array[i+1] = e;  
  54.         size ++;  
  55.     }  
  56.   
  57.     @Override  
  58.     public boolean isEmpty() {  
  59.         if(size == 0)  
  60.             return true;  
  61.         else   
  62.             return false;  
  63.     }  
  64.   
  65.     @Override  
  66.     public int lastIndexOf(Object e) {  
  67.         int i = size-1;  
  68.         while(i>=0 && !array[i].equals(e)) {  
  69.             i--;  
  70.         }  
  71.         if(i>=0)  
  72.             return i;  
  73.         else  
  74.             return -1;  
  75.     }  
  76.   
  77.     @Override  
  78.     public void remove(int i) {  
  79.         for(int j=i; j<size-1; j++) {  
  80.             array[j] = array[j+1];  
  81.         }  
  82.         size --;  
  83.     }  
  84.   
  85.     @Override  
  86.     public void set(int i, Object e) {  
  87.         array[i] = e;  
  88.     }  
  89.   
  90.     @Override  
  91.     public int size() {  
  92.         return size;  
  93.     }  
  94.     /** 
  95.      * 当顺序表的大小不够时,扩充顺序表的大小 
  96.      */  
  97.     private void expand() {  
  98.         maxLen = 2*maxLen;  
  99.         Object newArray[] = new Object[maxLen];  
  100.         for(int i=0; i<size; i++) {  
  101.             newArray[i] = array[i];  
  102.         }  
  103.         array = newArray;  
  104.     }  
  105.   
  106.     @Override  
  107.     public void add(Object e) {  
  108.         if(size >=maxLen)  
  109.             expand();  
  110.         array[size] = e;  
  111.         size ++;  
  112.     }  
  113. }  


单向循环链表

结构模型


带头结点的单链结构

  (a)空链;  (b)非空链 


源代码

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. package list;  
  2. /** 
  3.  * 链表的结点 
  4.  * @author luoweifu 
  5.  * 
  6.  */  
  7. class Node{  
  8.     Object data;    //数据元素  
  9.     Node next;      //后驱结点  
  10.     public Node() {  
  11.         this(null);  
  12.     }  
  13.     public Node(Object data) {  
  14.         this.data = data;  
  15.         this.next = null;  
  16.     }  
  17. }  
  18. /** 
  19.  * 带头结点的链式链表,下标从0开始;  
  20.  * @author Administrator 
  21.  * 
  22.  */  
  23. public class LinkList implements List {  
  24.     Node head;  //头结点  
  25.     int size;   //链表的大小  
  26.     public LinkList() {  
  27.         head = new Node();  
  28.         size = 0;  
  29.     }  
  30.     public LinkList(Object[] datas) {  
  31.         int n = datas.length;  
  32.         head = new Node();  
  33.         Node p = head;  
  34.         for(int i=0; i<n; i++) {  
  35.             p.next = new Node(datas[i]);  
  36.             p = p.next;  
  37.         }  
  38.         size = n;  
  39.     }  
  40.     @Override  
  41.     public void add(Object e) {  
  42.         Node p;  
  43.         if(0 == size) {  
  44.             p = head;  
  45.         } else {  
  46.             p = index(size-1);  
  47.         }  
  48.         p.next = new Node(e);  
  49.         size ++;  
  50.     }  
  51.   
  52.     @Override  
  53.     public void clear() {  
  54.         head.next = null;  
  55.         size = 0;  
  56.     }  
  57.   
  58.     @Override  
  59.     public Object get(int i) {  
  60.         Node p = index(i);  
  61.         return p.data;  
  62.     }  
  63.       
  64.     private Node index(int i) {  
  65.         Node p = null;  
  66.         if(i>=0 && i<size){  
  67.             p = head;  
  68.             for(int j=0; j<=i; j++) {  
  69.                 p = p.next;  
  70.             }  
  71.         }   
  72.         return p;  
  73.     }  
  74.   
  75.     @Override  
  76.     public int indexOf(Object e) {  
  77.         Node p = head.next;  
  78.         int i = 0;  
  79.         while(!p.data.equals(e)) {  
  80.             p = p.next;  
  81.             i++;  
  82.         }  
  83.         if(i<size)  
  84.             return i;  
  85.         else   
  86.             return -1;  
  87.     }  
  88.   
  89.     @Override  
  90.     public void insert(int i, Object e) {  
  91.         Node p = index(i);  
  92.         Node p2 = new Node(e);  
  93.         p2.next = p.next;  
  94.         p.next = p2;  
  95.         size ++;  
  96.     }  
  97.   
  98.     @Override  
  99.     public boolean isEmpty() {  
  100.         if(size ==0)  
  101.             return true;  
  102.         else  
  103.             return false;  
  104.     }  
  105.   
  106.     @Override  
  107.     public int lastIndexOf(Object e) {  
  108.         int i = size-1;  
  109.         while(!get(i).equals(e)) {  
  110.             i--;  
  111.         }  
  112.         if(i>=0)  
  113.             return i;  
  114.         else   
  115.             return -1;  
  116.     }  
  117.   
  118.     @Override  
  119.     public void remove(int i) {  
  120.         if(i>=0 && i<size) {  
  121.             Node p = null;  
  122.             if(i == 0)  
  123.                 p = head;  
  124.             else {  
  125.                 p = index(i-1);  
  126.             }  
  127.             p.next = index(i).next;  
  128.         }  
  129.         size --;  
  130.     }  
  131.   
  132.     @Override  
  133.     public void set(int i, Object e) {  
  134.         Node p = index(i);  
  135.         p.data = e;  
  136.     }  
  137.   
  138.     @Override  
  139.     public int size() {  
  140.         return size;   
  141.     }  
  142.       
  143. }  


双向循环链表

结构模型


带头结点的双循环链结构

 (a)空链;  (b)非空链 


源代码

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. package list;  
  2. /** 
  3.  * 链表的结点 
  4.  * @author luoweifu 
  5.  * 
  6.  */  
  7. class DlNode{  
  8.     Object data;  
  9.     DlNode prior, next;  
  10.     public DlNode() {  
  11.         this(null);  
  12.     }  
  13.     public DlNode(Object data) {  
  14.         this.data = data;   //数据元素  
  15.         this.prior = null;  //前驱结点  
  16.         this.next = null;   //后驱结点  
  17.     }  
  18. }  
  19. /** 
  20.  * 带头结点的双向循环链表,下标从0开始;  
  21.  * @author Administrator 
  22.  * 
  23.  */  
  24. public class DoubleLinkList implements List {  
  25.     DlNode head;    //头结点  
  26.     int size;   //链表的大小  
  27.     public DoubleLinkList() {  
  28.         head = new DlNode();  
  29.         head.prior = head;  
  30.         head.next = head;  
  31.         size = 0;  
  32.     }  
  33.     public DoubleLinkList(Object[] datas) {  
  34.         int n = datas.length;  
  35.         head = new DlNode();  
  36.         DlNode p = head;  
  37.         DlNode p2 = null;  
  38.         for(int i=0; i<n; i++) {  
  39.             p2 = new DlNode(datas[i]);  
  40.             p.next = p2;  
  41.             p2.prior = p;  
  42.             p = p.next;  
  43.         }  
  44.         p2.next = head;  
  45.         head.prior = p2;   
  46.         size = n;  
  47.     }  
  48.     @Override  
  49.     public void add(Object e) {  
  50.         DlNode p, p2;  
  51.         if(0 == size) {  
  52.             p = head;  
  53.         } else {  
  54.             p = index(size-1);  
  55.         }  
  56.         p2 = new DlNode(e);  
  57.         p.next = p2;  
  58.         p2.prior = p;  
  59.         p2.next = head;  
  60.         head.prior = p2;  
  61.         size ++;  
  62.     }  
  63.   
  64.     @Override  
  65.     public void clear() {  
  66.         head.prior = head;  
  67.         head.next = head;  
  68.         size = 0;  
  69.     }  
  70.   
  71.     @Override  
  72.     public Object get(int i) {  
  73.         DlNode p = index(i);  
  74.         return p.data;  
  75.     }  
  76.       
  77.     private DlNode index(int i) {  
  78.         DlNode p = null;  
  79.         if(i>=0 && i<size){  
  80.             p = head;  
  81.             for(int j=0; j<=i; j++) {  
  82.                 p = p.next;  
  83.             }  
  84.         }   
  85.         return p;  
  86.     }  
  87.   
  88.     @Override  
  89.     public int indexOf(Object e) {  
  90.         DlNode p = head.next;  
  91.         int i = 0;  
  92.         while(!p.data.equals(e)) {  
  93.             p = p.next;  
  94.             i++;  
  95.         }  
  96.         if(i<size)  
  97.             return i;  
  98.         else   
  99.             return -1;  
  100.     }  
  101.   
  102.     @Override  
  103.     public void insert(int i, Object e) {  
  104.         DlNode p = index(i);  
  105.         DlNode p2 = new DlNode(e);  
  106.         p2.next = p.next;  
  107.         p2.prior = p;  
  108.         p.next = p2;  
  109.         size ++;  
  110.     }  
  111.   
  112.     @Override  
  113.     public boolean isEmpty() {  
  114.         if(size ==0)  
  115.             return true;  
  116.         else  
  117.             return false;  
  118.     }  
  119.   
  120.     @Override  
  121.     public int lastIndexOf(Object e) {  
  122.         DlNode p = head.prior;  
  123.         int i = size-1;  
  124.         while(!p.data.equals(e)) {  
  125.             p = p.prior;  
  126.             i--;  
  127.         }  
  128.         if(i>=0)  
  129.             return i;  
  130.         else   
  131.             return -1;  
  132.     }  
  133.   
  134.     @Override  
  135.     public void remove(int i) {  
  136.         if(i>=0 && i<size) {  
  137.             DlNode p = null;  
  138.             if(i == 0)  
  139.                 p = head;  
  140.             else {  
  141.                 p = index(i-1);  
  142.             }  
  143.             DlNode p2 = index(i).next;  
  144.             p.next = p2.next;  
  145.             p2.next.prior = p;  
  146.         }  
  147.         size --;  
  148.     }  
  149.   
  150.     @Override  
  151.     public void set(int i, Object e) {  
  152.         DlNode p = index(i);  
  153.         p.data = e;  
  154.     }  
  155.   
  156.     @Override  
  157.     public int size() {  
  158.         return size;   
  159.     }  
  160.       
  161. }  

测试线性表

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. package list;  
  2.   
  3. public class Test {  
  4.   
  5.     /** 
  6.      * 测试线性表 
  7.      * @param args 
  8.      */  
  9.     public static void main(String args[]) {  
  10.         List list = new ArrayList();  
  11.         //List list = new LinkList();  
  12.         //List list = new DoubleLinkList();  
  13.         for(int i=0; i<10; i++) {  
  14.             list.add(new Integer(i));  
  15.         }  
  16.         list.remove(9);  
  17.         System.out.print("size;" + list.size() + "\n");  
  18.         System.out.println("isEmpty:" + list.isEmpty());  
  19.         System.out.print("第7个位置的元素:" + list.get(7) + "\n");   
  20.         for(int i=0; i<list.size(); i++) {  
  21.             System.out.print(list.get(i) + "    ");  
  22.         }  
  23.           
  24.         list.add(21);  
  25.         list.add(22);  
  26.         list.insert(3new Integer(5));  
  27.         System.out.print("size:" + list.size() + "\n");  
  28.         System.out.print("第一次出现5的索引:" + list.indexOf(5) + "\n");  
  29.         System.out.print("最后一次出现5的索引:" + list.lastIndexOf(5) + "\n");  
  30.         list.set(0new Integer(30));  
  31.         for(int i=0; i<list.size(); i++) {  
  32.             System.out.print(list.get(i) + "    ");  
  33.         }  
  34.     }  
  35. }  

结果

size;9
isEmpty:false
第7个位置的元素:7
0    1    2    3    4    5    6    7    8    size:12
第一次出现5的索引:4
最后一次出现5的索引:6
30    1    2    3    5    4    5    6    7    8    21    22   

0 0
原创粉丝点击