数据结构1——线性表

线性表分为顺序表和链式表,顺序表的存储结构为数组,而链式表的存储结构为指针,那么在java中淡化指针这个概念主要是通过对象引用的方式来表现指针。

1:顺序表

一般从两个方面来讲抽象数据类型:数据集合+操作集合

操作集合:可以将需要的操作定义为一个接口:

1 public interface List {
2     public void insert(int i, Object object)throws Exception;
3     public Object delete(int i) throws Exception;
4     public Object getDate(int i)throws Exception;
5     public int size();
6     public boolean isEmpty();
7     public int find(Object o);
8 }

1.1:顺序表在里面的具体实现

  1 public class SeqList implements List{
  2
  3     final int defaultSize=10;        //设置数组的默认大小
  4
  5     int maxSize;                //设置数组最大容量
  6     int size;                    //设置数组的当前的容量
  7     Object[] listArray;
  8
  9     //定义一个构造方法用于初始化数组的大小
 10     public  SeqList() {
 11         initiate(defaultSize);
 12     }
 13         //该构造方法用于自己定义数组的大小
 14     public  SeqList(int size) {
 15         initiate(size);
 16     }
 17
 18     //定义一个构造方法用于给maxSize赋值
 19     private void initiate(int sz) {
 20         maxSize=sz;
 21         size=0;
 22         listArray=new Object[sz];
 23     }
 24     /*
 25      * 在数组的第i个元素(在数组的i-1的位置)上面插入一个object值,并且插入后数组的数组不变,
 26      */
 27     @Override
 28     public void insert(int i, Object object) throws Exception {
 29         if (size==maxSize) {
 30             throw new Exception("顺序表格已经插满无法插入");
 31         }
 32         if (i<0||size<i) {
 33             throw new Exception("请输入合适的 参数");
 34         }
 35         //先移动再插入,从后面开始挪动  一定要先移动???thinking
 36         for(int j=size ;i< j ; j--){
 37             listArray[j]=listArray[j-1];
 38         }
 39             listArray[i]=object;
 40             size++;
 41     }
 42
 43     /*
 44      * 用于删除下标为i的数,同时不破坏数组的顺序
 45      */
 46     @Override
 47     public Object delete(int i) throws Exception {
 48         if (size==0) {
 49             throw new Exception("顺序表为空无法删除");
 50         }
 51         if (i<0||i>size-1) {
 52             throw new Exception("参数错误");
 53         }
 54         Object insert=listArray[i];
 55         //从下标为i+1的数开始挪动
 56         for (int j = i; j < size-1; j++) {
 57             listArray[j]=listArray[j+1];
 58         }
 59         size--;
 60         return insert;
 61     }
 62     /*
 63      * 获取数组中各个元素
 64      */
 65     @Override
 66     public Object getDate(int i) throws Exception {
 67         if (i<0||i>=size) {
 68             throw new Exception("参数错误");
 69         }
 70         return listArray[i];
 71     }
 72
 73     @Override
 74     public int size() {
 75         return size;
 76     }
 77
 78     @Override
 79     public boolean isEmpty() {
 80         return size==0;
 81     }
 82
 83     /*
 84      * 来定义一个方法用于一次性删除多个元素,并且不破坏数组的有序性,用tag来表记是否是第一次删除元素
 85      */
 86     public int MoreDataDelete(SeqList L,Object o) throws Exception{
 87         int j , i;
 88         int tag=0;
 89         for (i = 0; i < L.size; i++) {
 90             if (o.equals(L.getDate(i))) {
 91                 L.delete(i);
 92                 i--;
 93                 tag=1;
 94             }
 95         }
 96         return tag;
 97     }      //根据元素o查找o所在的位置
 98     @Override
 99     public int find(Object o) {
100         int ob=0;
101         int i=0;
102         while (i<=size&&o!=listArray[i])
103             i++;
104             if (i>size) {
105                 System.out.println("没找到");
106             }
107         return i;
108     }
109 }    

1.2:测试类

 1 public class Test1 {
 2
 3     /*
 4      * 前面insert()定义方法的时候参数一个为int类型,一个为object类型
 5      * 那么传入的I,必须转化为object类型
 6      */
 7     public static void main(String[] args)  {
 8
 9         SeqList sl=new SeqList(100);
10         int n=10;
11         try {
12             for (int i = 0; i < n; i++) {
13                 sl.insert(i, new Integer(i+1));
14                 }
15             sl.delete(4);
16             for (int i = 0; i < sl.size; i++) {
17                 System.out.print(sl.getDate(i)+" ");
18             }
19             } catch (Exception e) {
20                 e.printStackTrace();
21             }
22         }
23     }

2:链式表

单链式表包含两个元素,数据元素+指向下一个元素的指针

同时链表又分为单链表+双向链表

双向链表包含:前指针+元素+后指针

每一个新进来的元素都是插入到head结点中去

因此首先必须有一个表示该结点的类

 1 /*
 2  * 整个类使用于封装节点的类 必须包含element的元素,next的节点
 3  */
 4 public class Node {
 5     Object element;
 6     public Node next;
 7
 8     // 定义一个构造函数用于初始化头结点
 9     public Node(Node nextval) {
10         next = nextval;
11     }
12
13     // 定义一个构造函数用于初始化除了头结点以外的节点
14     public Node(Object o, Node nextval) {
15         element = o;
16         next = nextval;
17     }
18
19     public Object getElement() {
20         return element;
21     }
22
23     public void setElement(Object element) {
24         this.element = element;
25     }
26
27     public Node getNext() {
28         return next;
29     }
30
31     public void setNext(Node next) {
32         this.next = next;
33     }
34
35     //将获得的元素转化为String类型
36     public String toString(){
37         return element.toString();
38     }
39 }

2.1:链式表的操作集合

1 public interface List {
2     public Object findx(Object x);
3     public void insert(int i, Object object)throws Exception;
4     public Object delete(int i) throws Exception;
5     public Object getDate(int i)throws Exception;
6     public int size();
7     public boolean isEmpty();
8 }

2.2:单链式表的具体实现方法

 1 package com.hone.SingleLinkedList;
 2
 3 import com.hone.SingleLinkedList.order.Node;
 4
 5 public class LinList implements List{
 6
 7     public Node head;                        //head表示头指针
 8     Node currentNode;                //currentNode表示当前指针
 9     public int size;                        //表示元素的多少
10
11     //构造一个构造函数用于初始化head,currentnode节点,以及初始化size的大小
12     public LinList(){
13         head=currentNode=new Node(null);
14         size=0;
15     }
16
17     // 定义一个方法用于确定参数i节点所在的位置,并且用当前位置的currentnode来表示i节点
18     public void index(int i) throws Exception{
19         if(i<-1||i>size-1){
20                 throw new Exception("参数输入有误");
21         }
22         if(i==-1) return;
23         currentNode=head.next;
24         int j=0;
25         while(currentNode!=null&&j<i){
26             currentNode=currentNode.next;
27             j++;
28         }
29     }
30
31     // 在数组的第i个元素(i-1个结点)上面插入一个object值,并且插入后数组的数组不变
32     @Override
33     public void insert(int i, Object object) throws Exception {
34         if (i<0||i<size) {
35             throw new Exception("请输入合适的 参数");
36         }
37         index(i-1);            //找出I-1指针的位置
38         currentNode.setNext(new Node(object, currentNode.next));
39         size++;
40     }
41
42     // 用于删除下标为i的数,同时不破坏数组的顺序
43     @Override
44     public Object delete(int i) throws Exception {
45         if (size==0) {
46             throw new Exception("顺序表为空无法删除");
47         }
48         if (i<0||i>size-1) {
49             throw new Exception("参数错误,请输入正确的参数");
50         }
51
52         index(i-1);            //找到第i-1个结点
53         Object object=currentNode.next.getElement();//获得删除的那个元素
54         currentNode.setNext(currentNode.next.next);
55         size--;
56         return object;
57     }
58
59     // 获取数组中各个元素
60     @Override
61     public Object getDate(int i) throws Exception {
62         if (i<0||i>=size) {
63             throw new Exception("参数错误");
64         }
65         index(i);
66         return currentNode.getElement();
67     }
68
69     //获得单链表的大小
70     @Override
71     public int size() {
72         return size;
73     }
74
75     //判断单链表是否为空值
76     @Override
77     public boolean isEmpty() {
78         return size==0;
79     }
80
81     //根据未知数x来查找它所在的位置
82     @Override
83     public Object findx(Object x) {
84         while(currentNode!=null&&currentNode.getElement()!=x)
85             currentNode=currentNode.next;
86         return currentNode;
87     }
88 }
 1 public class LinTest {
 2     /*
 3      * 前面insert()定义方法的时候参数一个为int类型,一个为object类型
 4      * 那么传入的I,必须转化为object类型
 5      */
 6     public static void main(String[] args)  {
 7
 8         LinList ll=new LinList();
 9         int n=10;
10
11         try {
12             for (int i = 0; i < n; i++) {
13                 ll.insert(i, new Integer(i+1));
14                 }
15
16             ll.delete(4);
17             for (int i = 0; i <ll.size; i++) {
18                 System.out.print(ll.getDate(i)+" ");
19             }
20             } catch (Exception e) {
21                 e.printStackTrace();
22             }
23         }
24     }

2.3:双向链表的具体实现

利用链表将数组排序

 1 import java.util.Comparator;
 2 import com.hone.SingleLinkedList.LinList;
 3
 4 public class OrderList {
 5
 6     //为链表排序
 7     public static void orderInsert(LinList mylist,Object x, Comparator mc){
 8         Node cur;
 9         Node pre;
10         //每一个新进来的节点都是头结点
11         cur=mylist.head.next;
12         pre=mylist.head;
13         while (cur!=null&&(mc.compare(cur.element, x )==1)) {
14             pre=cur;
15             cur=cur.next;
16         }
17         Node temp=new Node((Integer)x, pre.next);
18         pre.next=temp;
19         mylist.size++;
20     }
21
22     public static void main(String[] args) throws Exception {
23         MyConparator mc= new MyConparator();
24         LinList myList=new LinList();
25         int s[] ={1,2,4,7,33,67,10,56,89,45,7,4,3};
26         for (int i = 0; i < s.length; i++) {
27             orderInsert(myList, new Integer(s[i]), mc);
28         }
29         for (int i = 0; i <myList.size; i++) {
30             System.out.print(myList.getDate(i)+" ");
31         }
32     }
33 }

总的来说:顺序表和链式表格都有自己的优势

顺序表:因为本身数组表在逻辑+物理内存上面都是相连的,因为顺序表在随机读取,内存空间利用效率上面具有较大的优势。

    但是由于顺序表,必须在事先知道数组的大小,因为可扩展性没有链式表大,其次每次插入(前面说过是从最后一项开始移动),删除都得移动较多的元素。

链式表:优点自然是不需要提前知道元素的个数。

java中已经给我们封装好了顺序表和链式表。(ArrayList/LinkedList)。

时间: 2024-10-10 20:56:03

数据结构1——线性表的相关文章

自学数据结构——顺序线性表

胡乱写了一些代码 /* ============================================================================ Name : sqlist.c Author :codecup Version : Copyright : Your copyright notice Description : Hello World in C, Ansi-style ==========================================

软考之路--数据结构之线性表

数据就是数值,也就是我们通过观察.实验或计算得出的结果.数据有很多种,最简单的就是数字.数据也可以是文字.图像.声音等.数据可以用于科学研究.设计.查证等.结构,组成整体的各部分的搭配和安排,两者完美结合在一起,我们这样需要重新认识她,对她重新审视与定义:数据结构是程序设计的重要理论和技术基础,她所讨论的内容和技术,对从事软件项目的开发有重要作用,通过学习数据结构,我们学会从问题出发,分析和研究计算机加工的数据的特性,以便为应用所设计的数据悬着适当的逻辑结构.存储结构及其相应的操作方法,为提高应

[笔记]python数据结构之线性表:linkedlist链表,stack栈,queue队列

python数据结构之线性表 python内置了很多高级数据结构,list,dict,tuple,string,set等,在使用的时候十分舒心.但是,如果从一个初学者的角度利用python学习数据结构时,这些高级的数据结构可能给我们以迷惑. 比如,使用list实现queue的时候,入队操作append()时间复杂度可以认为是O(1),但是,出队操作pop(0)的时间复杂度就是O(n). 如果是想利用python学学数据结构的话,我觉得还是自己实现一遍基本的数据结构为好. 1.链表 在这里,我想使

自学数据结构——顺序线性表2

1 /* 2 ============================================================================ 3 Name : sqlist.c 4 Author : codecup 5 Version : 6 Copyright : Your copyright notice 7 Description : Hello World in C, Ansi-style 8 ==================================

数据结构:线性表插入一次删除一次的代码

#include <iostream> #include <cmath> #include <cstring> #include <algorithm> #include <stack> #include <queue> #include <cstdio> using namespace std; int insertsqlist(int weizhi,double charu,int *t,double b[]){   

数据结构之线性表(顺序存储结构)

小学生放学都是要按顺序排队的,一个接一个,每个小学生的前后位置是固定的,这样便于迅速清点. 其实这就是一个线性表,从这件事里我们就可以找到很多关于线性表的特性,如 1.线性表是一个序列,它是有顺序的(排队) 2.第一个元素无前驱,最后一个无后继,其他每个元素都有一个前驱和后继(一个接一个) 3.元素是有限的(小学生的个数是有限的) 4.数据类型都相同(都是小学生在排队) 说明白线性表示什么,下面我们直接看线性表的实现 线性表的实现分顺序存储结构和链式存储结构 顺序存储结构: #define LI

数据结构:线性表之单链表

线性表(亦作顺序表)是最基本.最简单.也是最常用的一种数据结构.线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的.线性表有两种存储结构: ①顺序存储结构,即存储单元在一段连续的地址上存储,常见的数组就是顺序存储结构的线性表: ②链式存储结构,即存储单元在不连续的地址上存储.因为其不连续性,除了要存数据元素信息(数据域)外,还要存储它后继元素(结点)的地址(指针域,链).学习链式结构最好将结点结构牢记于心,如下图: 链表的每个结点只含有一个指

数据结构之线性表

线性表是最简单最常用的一种数据结构,在生活中各个方面都有应用. 线性表的定义:线性表大多数情况下是除了第一个位置的数据元素只存在后继元素,最后一个位置的数据元素只存在前驱元素外,所有数据元素都存在前驱和后继的一个有限序列.举个简单的例子就是:字母表中除了 a 只存在后继 b,z 只存在前驱 y之外,剩余的所有字母全部都有前驱和后继.为什么是大多数情况下,是因为线性表的链式存储结构中除了单向链表,还有循环链表和双向链表. 线性表的存储结构:顺序存储(数组实现,需要预先分配连续的内存空间)和链式存储

浅谈数据结构之线性表顺序存储(一)

 首先,数据结构是由某一数据元素集合及该集合中所有数据元素之间的关系组成.具体来说,数据结构应当包含三方面的内容:(1).数据的逻辑结构:(2).数据的存储结构:(3).对数据所施加的操作.而数据的存储结构形式有两种:顺序存储与链式存储.在这里,先谈一谈线性表的顺序存储. 线性表:零个或多个数据元素的有限序列.第一,它是一个序列,也就是说,元素之间是有顺序的:第二,它是有限的,即元素个数是有限的.而线性表的顺序存储结构,说白了,就是在内存中找块地,通过占位的形式把一定的内存空间给占了,然后把相同

数据结构_线性表的顺序表示和链式表示

/********************************************************************************************************************/ 声明: (1)*.h文件是代码声明, *.cpp文件是代码实现; (2)一般头文件的内容有: ①类型声明; ②函数声明; ③枚举; ④常量; ⑤宏 (3)以下说明是为了方便代码文件的管理而设定的一些规则, 以后代码都会按照此规则编写: 1)Pubuse.h 是几