数据结构(一)顺序表、链表以及队列
2015-07-16 12:32
375 查看
一、顺序表
顺序表:它具有连续内存地址。访问方便O(1),但是删除和插入不方便O(N)。常用数组实现。
在J***A中,声明一个数组直接使用语句:
当然J***A中本身自带了很多封装的数组,如Arrays,ArrayList,Stack等。
这里给出了简单的数组的插入与删除。
当然对于数组类Arrays,它本身也有很多方便的方法,如:
以及栈类Stack
栈的特点是:只能在表的一端进行插入与删除操作,先进后出LIFO。它有两个基本操作:出栈和入栈
使用顺序表stack与栈顶指针top来实现栈
需要注意的是:插入的时候需要判断栈是否已满,而删除的时候要判断栈是否为空。常用来设计如下题型:
判断字符串的括号匹配
J***A中的栈则如下:
以及ArrayList, Set ,Map 等Collection类。大部分都有类似的方法。但是它们每种都有自己的特点。详情见:http://www.lai18.com/content/1638954.html
二、链表
相对于顺序表的定位快,插入删除慢,链表则不同,它通过指针将不同位置的元素链接起来,因而优缺点与数组正好相反:定位慢(O(n)),插入删除快(O(1))。链表一般用指针动态分配内存来实现。
在J***A中有常见的集合类 LinkedList(它的实现采用的是链表机制)。使用之前要先导入包:
声明链表如下:
这里的Integer可以换成其他的对象。如String,Double,以及自定义类。
LinkedList的方法也不外乎有:插入,删除,判空,size(),判断是否含有某对象等等。这里不在一一叙述。
除此之外:也可以自定义链表,如:
首先定义一个链表的结点类
其次声明链表其实就是已知一个头结点即可。
当然对于链表还需要一个一个构建,将各个链表结点链接起来。
同理,还可以定义双向链表
三、队列
队列是这样一种表:只能在一端(队尾)插入,另一端(对头)删除。
队列的实现:一般用顺序表queue,队首指针front和队尾指针rear来实现队列。它有两个基本操作:入队(enqueue),出队(dequeue)
即不移动元素而是移动指针。这样操作很快,但是表前面的位置是浪费的。
因此有一种特殊的队列是:循环队列,可以避免这种浪费。首先规定一个队列长度size,入队和出队因此变为:
J***A中队列的实现:优先队列(说到底也是一种Collection)
首先引入包
声明优先队列,以及一些方法。
在这种队列中,入队的顺序是无关的,每次都选一个优先级最小的元素出队。
顺序表:它具有连续内存地址。访问方便O(1),但是删除和插入不方便O(N)。常用数组实现。
在J***A中,声明一个数组直接使用语句:
int[] array = new int[k];k为已知的数组大小。
当然J***A中本身自带了很多封装的数组,如Arrays,ArrayList,Stack等。
[code]import java.util.Arrays; /**数组的基本操作,包括插入,删除等,以整数数组为例进行操作 * * @author wenbaoli * @version 1.0 */ public class Array { /** 数组插入元素 * @param arr 数组 * @param k 插入的位置 * @param x 插入的元素 * @return 返回插入元素后的数组 */ public static int[] Insert(int[] arr,int k,int x){ if(k > arr.length || k < 0){ System.out.println("插入的位置非法!"); return null; } int[] temp = new int[arr.length+1]; for(int i = 0;i< k; i++){ temp[i] = arr[i]; } temp[k] = x; for(int i = k+1 ;i<temp.length;i++){ temp[i] = arr[i-1]; } arr = temp;//这里即使改变arr,在main函数中也无法得到改变后的数组,因为方法传递的是arr的拷贝,而不是真正意义上的arr return temp; } /**删除数组中指定位置的元素 * @param arr 数组 * @param k 指定的位置 * @return 返回删除元素后的数组 */ public static int[] Delete(int[] arr,int k){ int[] temp = new int[arr.length - 1]; for(int i = 0; i < k; i++){ temp[i] = arr[i]; } for(int i = k+1; i < arr.length; i++){ temp[i - 1] = arr[i]; } return temp; } public static void print(int[] arr){ for(int n : arr){ System.out.print(n + "\t"); } System.out.println(); } /** 对本类中的方法进行测试 * * @param arg */ public static void main(String[] arg){ //initial int[] arr = {1,2,3,4,5,6,7,8,9,0}; print(arr); int[] temp; //insert operation temp = Insert(arr,5,11); arr = temp;//在main函数中改变arr首地址的话是可以得到改变后的数组的。 print(arr);//此时的arr就是改变后的数组temp //delete operation temp = Delete(arr,5); arr = temp; print(arr); //other operation using J***A package Arrays.sort(arr);//利用java包Array,对数组进行排序 print(arr); } }
这里给出了简单的数组的插入与删除。
当然对于数组类Arrays,它本身也有很多方便的方法,如:
[code]Arrays.sort(arr); Arrays.binarySearch(arr,key); Arrays.fill(arr,x);
以及栈类Stack
栈的特点是:只能在表的一端进行插入与删除操作,先进后出LIFO。它有两个基本操作:出栈和入栈
使用顺序表stack与栈顶指针top来实现栈
[code]//这个操作一般是C/c++语言操作 stack[top++] = item;//入栈 item = stack[--top];//出栈
需要注意的是:插入的时候需要判断栈是否已满,而删除的时候要判断栈是否为空。常用来设计如下题型:
判断字符串的括号匹配
J***A中的栈则如下:
[code]import java.util.Stack; /**对J***A中自带栈的测试,分别对其各个函数进行了了解与说明。这里的栈更像是一个数组,可以插入与删除(这不是栈的本来定义)。只能出栈与入栈(在一端)才是栈的特点。 * * @author wenbaoli * */ public class StackTest { public static void main(String[] args){ Stack<Integer> stack = new Stack<Integer>(); for(int i = 0; i < 10;i++){ stack.add(i); } System.out.println(stack); System.out.println(stack.peek());//peek()函数只定位到栈顶的值,并不会出栈 System.out.println(stack);//此时栈还是原来的 System.out.println(stack.pop());//pop()函数会出栈。 System.out.println(stack);//此时栈已经改变(栈顶元素已经出栈了) stack.add(3, 10);//在索引为3的位置插入元素10. System.out.println(stack); stack.remove(3);//去除索引为3的元素 System.out.println(stack); stack.push(9);//将元素9入栈。 System.out.println(stack); stack.addElement(10);//此函数相当于入栈 System.out.println(stack); System.out.println(stack.capacity());//当前栈的容量(这个值可能大于已有的元素个数) System.out.println(stack.contains(11));//判断是否含有指定元素,返回false or true System.out.println(stack.empty());//判空函数,返回false or true System.out.println(stack.search(5));//返回元素5所在的索引值 System.out.println(stack.capacity()); stack.trimToSize();//将栈的容量改为当前元素所占用的量 System.out.println(stack.capacity());//此时的容量即为元素个数 System.out.println(stack.size()); } }
以及ArrayList, Set ,Map 等Collection类。大部分都有类似的方法。但是它们每种都有自己的特点。详情见:http://www.lai18.com/content/1638954.html
二、链表
相对于顺序表的定位快,插入删除慢,链表则不同,它通过指针将不同位置的元素链接起来,因而优缺点与数组正好相反:定位慢(O(n)),插入删除快(O(1))。链表一般用指针动态分配内存来实现。
在J***A中有常见的集合类 LinkedList(它的实现采用的是链表机制)。使用之前要先导入包:
[code]import java.util.LinkedList;
声明链表如下:
[code]LinkedList<Integer> llist = new LinkedList<Integer>();
这里的Integer可以换成其他的对象。如String,Double,以及自定义类。
LinkedList的方法也不外乎有:插入,删除,判空,size(),判断是否含有某对象等等。这里不在一一叙述。
除此之外:也可以自定义链表,如:
首先定义一个链表的结点类
[code]public class SingleLinkList{ int data; SingleLinkList next; }
其次声明链表其实就是已知一个头结点即可。
[code]SingleLinkList h;
当然对于链表还需要一个一个构建,将各个链表结点链接起来。
同理,还可以定义双向链表
[code]public class DoubleLinkList{ int data; DoubleLinkList prior; DoubleLinkList next; }
三、队列
队列是这样一种表:只能在一端(队尾)插入,另一端(对头)删除。
队列的实现:一般用顺序表queue,队首指针front和队尾指针rear来实现队列。它有两个基本操作:入队(enqueue),出队(dequeue)
[code]queue[++rear] = item;//入队 queue[++front] = item;//出队
即不移动元素而是移动指针。这样操作很快,但是表前面的位置是浪费的。
因此有一种特殊的队列是:循环队列,可以避免这种浪费。首先规定一个队列长度size,入队和出队因此变为:
[code]//入队 rear = (rear + 1) % size; queue[rear] = item; //出队 front = (front + 1) % size; queue[front] = item;
J***A中队列的实现:优先队列(说到底也是一种Collection)
首先引入包
[code]import java.util.PriorityQueue;
声明优先队列,以及一些方法。
[code]PriorityQueue<Integer> pq = new PriorityQueue<Integer>(); pq.add(3); System.out.println(pq); pq.peek(); pq.poll();
在这种队列中,入队的顺序是无关的,每次都选一个优先级最小的元素出队。
相关文章推荐
- 第13章 数据结构基础
- 高级数据结构-树状数组总结
- 转载: 数据结构之图(存储结构、遍历)
- 数据结构基础 之 二叉堆实现堆排序
- 二叉树的存储结构与前序遍历(中序/后序原理一样)
- 《数据结构》--线性表
- 《数据结构》--和多项式链表
- java 数据结构基本算法希尔排序
- 数据结构 ---- 二叉搜索树
- 八大排序算法
- PAT 数据结构 06-图4. Saving James Bond - Hard Version (30)
- 数据结构 树状数组
- 【自考学习】——《数据结构导论》概览
- PAT 数据结构 05-图3. 六度空间 (30)
- 算法导论 第十章:基本数据结构
- 图的存储
- PAT 数据结构 05-图2. Saving James Bond - Easy Version (25)
- VoiceEngine Codec数据结构
- PAT 数据结构 05-图1. List Components (25) 深度搜索DFS和广度搜索BFS
- C语言-数据结构(一)