大话数据结构读书笔记(三)-线性表

来源:互联网 发布:ubuntu 16.10 安装后 编辑:程序博客网 时间:2024/06/02 09:24

一、绪论

二、算法

三、线性表

四、栈和队列

五、串

六、树

七、图

八、查找

九、排序

                                     三、线性表

线性表定义:另个或多个数据元素的有限序列(除第一个无前驱和最后一个无后续)(有限、有序)。

表长:线性表元素个数定义为表的长度,n=0时称为空表。

复杂情况下一个数据元素可以有多个数据项组成。

线性表的基本操作:

import java.util.ArrayList;import java.util.List;public class Linner {  //  构造一个空的线性表      public List<Integer> create(){          return new ArrayList<Integer>();      }  //  初始化线性表      private void init(int length,List<Integer> list) {          for(int i=1;i<=length;i++){              list.add(i);          }      }  //  销毁线性表      private void destroy(List<Integer> list){          list = null;      }  //  清空线性表      private void clear(List<Integer> list){          list.clear();      }  //  判定线性表是否为空      private boolean isEmpty(List<Integer> list){          return list.isEmpty();      }  //  表长度      private int length(List<Integer> list){          return list.size();      }  //  获取第i个数据元素的值      private int getNum(int getNum,List<Integer> list) {          for (int i=0;i<list.size();i++){              if(i==getNum){                  return (int)list.get(i);              }          }          return -1;      }  //  删除第i个数据元素      private void DeleteNum(int deleteNum,List<Integer> list) {          for (int i=0;i<list.size();i++){              if((int)list.get(i)==deleteNum){                  list.remove(i);              }          }      }  //  非第一元素,返回前驱      private int getPrior(int indexNum,List<Integer> list){          return list.get(indexNum-1);      }  //  非最后一个元素,返回后继      private int getNext(int indexNum,List<Integer> list){          return list.get(indexNum+1);      }  //  列举线性表的所有元素      private void dump(List<Integer> list) {          for(int i=0;i<list.size();i++){              System.out.println(list.get(i));          }      }            public static void main(String args[]){                      Linner l=new Linner();         List<Integer> list= l.create();         l.init(10, list);    }    }
线性表的顺序存储结构:指用一连续地址存储单元一次存储线性变的元素,对于获取对应位置元素很方便。存取时间性能O(1)。而在插入与删除时的时间复杂度是O(n)。线性表适合数据元素不多,而操作多是存取的应用。

线性表的优缺点:无需为表的逻辑结构增加额外的存储空间,可以快速的存取表中的任何一位置的元素,缺点:插入和删除移动大量的元素,当线性表长度变化较大时难以确定存储空间的容量,造成存储空间的碎片。

线性表的链式存储:线性表只需要存储元素,在链式存储中不仅要存储元素还要存储后继元素的存储地址。(数据域与指针域组合成结点)。n个结点组合成链表。链表第一个结点的存储位置为头指针。

头结点与头指针:头指针是指链表指向第一个结点的指针,如链表有头结点则指向头结点,无论链表是否为空,头指针均不为空,头指针是链表的必要元素。头结点:是为了操作统一和方便设立的放在第一个元素前面,其数据域一般无意义,有了头结点对第一个元素的节点前的插入和删除操作就统一了。头结点不一定是链表必要。

链表的操作

public class Listlink {public class Node {     protected Node next; //指针域       protected int data;//数据域              public Node( int data) {             this. data = data;       }              //显示此结点       public void display() {            System. out.print( data + " ");       }  }  public class LinkList {       public Node first; // 定义一个头结点       private int pos = 0;// 结点的位置       public LinkList() {             this. first = null;       }       // 插入一个头节点       public void addFirstNode( int data) {            Node node = new Node(data);            node. next = first;             first = node;       }       // 删除一个头结点,并返回头结点       public Node deleteFirstNode() {            Node tempNode = first;             first = tempNode. next;             return tempNode;       }       // 在任意位置插入节点 在index的后面插入       public void add(int index, int data) {            Node node = new Node(data);            Node current = first;            Node previous = first;             while ( pos != index) {                previous = current;                current = current. next;                 pos++;            }            node. next = current;            previous. next = node;             pos = 0;       }         // 删除任意位置的节点       public Node deletePos( int index) {            Node current = first;            Node previous = first;             while ( pos != index) {                 pos++;                previous = current;                current = current. next;            }             if(current == first) {                 first = first. next;            } else {                 pos = 0;                previous. next = current. next;            }             return current;       }         // 根据节点的data删除节点(仅仅删除第一个)       public Node deleteData( int data) {            Node current = first;            Node previous = first; //记住上一个节点             while (current. data != data) {                 if (current. next == null) {                      return null;                }                previous = current;                current = current. next;            }             if(current == first) {                 first = first. next;            } else {                previous. next = current. next;            }             return current;       }         // 显示出所有的节点信息       public void displayNodes() {            Node current = first;             while (current != null) {                current.display();                current = current. next;            }            System. out.println();       }         // 根据位置查找结点信息       public Node findPos( int index) {            Node current = first;             if ( pos != index) {                current = current. next;                 pos++;            }             return current;       }         // 根据数据查找结点      public Node findData( int data) {            Node current = first;             while (current. data != data) {                 if (current. next == null)                      return null;                current = current. next;            }             return current;       }   }public static void main(String[] args) {}}
单链表的优缺点:存取物理位置随意不需要连续的单元,查找时间复杂度O(n),插入与删除O(1),空间性能顺序表需要预先分配存储空间,链表不需要。

静态链表:用数组描述的链表叫静态链表,这里的数组元素包含两个数据域(data和cur)cur相当于链表的next指针叫游标。静态链表的优缺点:在插入和删除操作时只需要移动游标,不需要移动元素,缺点是没有解决存储分配带来的表长难以确定的问题,失去顺序存储结构随机存储的特性。

循环链表:将单链表的终端结点的指针由空改为指向头结点,就是整个单链表形成一个环形成单链表。循环链表的操作与单链表基本一致,差别在于算法中的循环条件不是p或者p->next是否为空, 而是他们是否等于头指针。

class rcode{    private Object data; //定义数据域    private rcode nextreode; //定义下一个节点    private rcode head=null;//定义头节点    public Object getData() {        return data;    }    public void setData(Object data) {        this.data = data;    }    public rcode getNextreode() {        return nextreode;    }    public void setNextreode(rcode next) {        this.nextreode = next;    }    public void initCycleList(Object data){ //循环链表的初始化        head=new rcode();        head.setData(data);        head.setNextreode(head);    }    public void insertCycleListTail(Object data){        rcode inCNode=new rcode();        inCNode.setData(data);        if (head==head.getNextreode()) { //如果原链表只有一个节点,直接插入            head.setNextreode(inCNode);            inCNode.setNextreode(head);        }else {  //原链表不止一个节点            rcode temp=head; //创建临时节点            while (head!=temp.getNextreode()) { //遍历循环链表,找到最后一个节点                temp=temp.getNextreode();            }            temp.setNextreode(inCNode); //插入节点            inCNode.setNextreode(head);         }    }    //求循环链表的长度    public int cycleListSize(){        rcode temp=head;        int size=0;        while (temp.getNextreode()!=head) {            size++;            temp=temp.getNextreode();        }        return size;    }    //判断循环链表中是否存在某个元素    public Boolean isContain(Object data){        rcode temp=head;        while (temp.getNextreode()!=head) {            if (temp.getData().equals(data)) {                return true;            }            temp=temp.getNextreode();        }        return false;    }    //获取循环链表中第i个位置的元素    public rcode getCNode(int i){        if (i<0||i>cycleListSize()) {            System.out.println("输入有误");            return null;        }else {            int count=0;            rcode temp=head;            rcode retCNode=new rcode();            while (head!=temp.getNextreode()) {                if (count==i) {                    retCNode.setData(temp.getData());                    break;                }                temp=temp.getNextreode();                count++;            }            return retCNode;        }    }    //打印循环链表    public void printCycleList(){        rcode temp=head;        while (head!=temp.getNextreode()) {            System.out.print(temp.getData()+" ");            temp=temp.getNextreode();        }        System.out.println();    }}public class reviList {public static void main(String[] args) {}}
双向链表:在双向链表的结点中有两个指针域, 其一指向直接后继,另一指向直接前驱。

0 0
原创粉丝点击