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

一、绪论

二、算法

三、线性表

四、栈和队列

五、串

六、树

七、图

八、查找

九、排序

                                     三、线性表

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

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

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

线性表的基本操作:

import java.util.ArrayList;
import java.util.List;
public class Linner {	  
	//  构造一个空的线性表  
	    public List create(){  
	        return new ArrayList();  
	    }  
	//  初始化线性表  
	    private void init(int length,List list) {  
	        for(int i=1;i<=length;i++){  
	            list.add(i);  
	        }  
	    }  
	//  销毁线性表  
	    private void destroy(List list){  
	        list = null;  
	    }  
	//  清空线性表  
	    private void clear(List list){  
	        list.clear();  
	    }  
	//  判定线性表是否为空  
	    private boolean isEmpty(List list){  
	        return list.isEmpty();  
	    }  
	//  表长度  
	    private int length(List list){  
	        return list.size();  
	    }  
	//  获取第i个数据元素的值  
	    private int getNum(int getNum,List list) {  
	        for (int i=0;i list) {  
	        for (int i=0;i list){  
	        return list.get(indexNum-1);  
	    }  
	//  非最后一个元素,返回后继  
	    private int getNext(int indexNum,List list){  
	        return list.get(indexNum+1);  
	    }  
	//  列举线性表的所有元素  
	    private void dump(List list) {  
	        for(int i=0;i 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) {
		
	}
}

双向链表:在双向链表的结点中有两个指针域, 其一指向直接后继,另一指向直接前驱。

 

你可能感兴趣的:(大话数据结构读书笔记)