数据结构-第一个博客
如果不是为了提交作业,估计都现在都还不知道博客这个东西怎么写,现在也不是很清楚,只能大概用我刚学会的这点方式写了,比较粗糙,以后慢慢改进。以下内容仅是本人的粗浅理解以及在学习过程中的总结。
数据结构包括数据的逻辑结构和存储结构两种。
逻辑结构:数据元素之间相互联系的方式,可分为线性结构、树形结构、图结构;
存储结构:数据元素在计算机中的存储方式,一般有两种形式:顺序存储结构和链式存储结构;具体用哪一种需要根据实际问题来确定。
数组
数组是最常用的数据结构,所有线性结构(线性表、堆栈、队列)的顺序存储结构其实就是使用数组来存储,因此数组是实现顺序结构的基础
-
定义
数组是n个具有相同数据类型的数据元素构成的占用一块连续内存单元的有限集合。 -
特点
数组在内存中地址是连续的,所以根据数组下标便可以表示数据元素。 -
与线性表的异同
相同点:数组和线性表都由若干个相同数据类型的数据组成的有限集合。
不同点:(1)数组要求其元素占用一块地址连续的内存空间,而线性表没有这个要求,可连续也可以不连续;
(2)线性表的元素在逻辑意义上是不可再分的元素,而数组中的每个元素还可以是一个数组,例如二位数组可以看做由一位数组组成的数组;
(3)数组的操作主要是对某个下标所对应元素的存取操作,与线性表的删除、插入操作不同。
动态扩容数组
数组本身大小是固定的,一旦创建了数组,就不能改变他的大小。如果需要在使用过程中经常扩展数组大小,可以用另外一种数据结构-数组列表。在学习数据的过程中发现可数组另一种方式-数组拷贝。程序如下
import java.util.*;
public class Arrayexpand {
static int[] array=new int[10];
public static void main(String[] args)
{
for(int i=0;i<array.length;i++)
array[i]=i+1;
System.out.print("扩容之前array");
System.out.println(Arrays.toString(array));
array=newLengtharray(array);
System.out.print("扩容之后array");
System.out.println(Arrays.toString(array));
}
public static int[] newLengtharray(int[] array)
{
int[] newarray=new int[array.length*2];
System.arraycopy(array, 0, newarray, 3, array.length-2);
return newarray;
}
}
两个有序数组合并为一个有序数组
1.因为刚学了数组拷贝的方法,于是就现学现用,创建一个新的数组c,长度为数组a和b的长度之和,将数组a和数组b都拷贝到c中,然后对c进行排序
2.类似于归并排序的方法,遍历下标
import java.util.Arrays;
public class Arraymerge
{
//第一种方法
public static int[] arraymerge1(int[] a,int[] b)
{
int m=a.length;
int n=b.length;
int[] c=new int[m+n];
int i=0;
int j=0;
int k=0;
while(i<m&&j<n)
if(a[i]<=b[j])
{
c[k++]=a[i++];
}
else
{
c[k++]=b[j++];
}
while(i<m)
c[k++]=a[i++];
while(j<n)
c[k++]=b[j++];
return c;
}
//第二种方法
public static int[] arraymerge2(int[] a,int[] b)
{
int[] c=new int[a.length+b.length];
System.arraycopy(a, 0, c, 0, a.length);
System.arraycopy(b, 0, c, a.length, b.length);
Arrays.sort(c);
return c;
}
public static void main(String[] args)
{
int[] a= {3,7,9,12};
int[] b= {1,2,5,8,15};
int[] c= {4,6,10,13,14};
int[] c1=arraymerge1(a,b);
int[] c2=arraymerge2(c,b);
System.out.println("数组a:"+Arrays.toString(a));
System.out.println("数组b:"+Arrays.toString(b));
System.out.println("第一种方法合并后数组c1:"+Arrays.toString(c1));
System.out.println("第二种方法合并后数组c2:"+Arrays.toString(c2));
}
}
大小固定的数组支持增删改查
import java.util.*;
public class ArrayOK
{
///插入
public static int[] insert(int[] array,int i,int obj)
{
int[] newarray=new int[array.length+1];
System.arraycopy(array, 0, newarray, 0, array.length);
for(int j=array.length;j>i;j--)
newarray[j]=newarray[j-1];
newarray[i]=obj;
return newarray;
}
//删除
public static int[] delete(int[] array,int i)
{
for(int j=i;j<array.length-1;j++)
array[j]=array[j+1];
array[array.length-1]=0;
int[] newarray=Arrays.copyOf(array, array.length-1);
return newarray;
}
//修改
public static int[] modify(int[] array,int i,int obj)
{
array[i]=obj;
return array;
}
public static void main(String[] args)
{
int[] array= {2,3,5,6,9};
array=insert(array,3,4);
System.out.println("插入元素之后array"+Arrays.toString(array));
array=delete(array,2);
System.out.println("删除元素之后array"+Arrays.toString(array));
array=modify(array,1,89);
System.out.println("修改元素之后array"+Arrays.toString(array));
}
}
单链表
单链表是线性表的链式存储结构。链式存储结构是基于指针实现的。一个数据元素和一个指针成为一个结点。链式存储结构是用指针把相互直接关联的结点连接起来。要实现单链表首先要定义结点类Node,然后定义单链表类LinList
在这里插入代码public class Node {
Object data;
Node next;
public Node(Node nextval) {//头结点构造方法
next=nextval;
}
public Node(Object obj,Node nextval) {//非头结点构造方法
data=obj;
next=nextval;
}
public Node getNext() {//获取指针域
return next;
}
public void setNext(Node nextval) {//设置指针域
next=nextval;
}
public Object getElement() {//获取数据域
return data;
}
public void setElement(Object obj) {//设置指针域
data=obj;
}
public String toString() {
return data.toString();
}
}
public class LinList {
Node head;//头指针
Node current;//当前结点对象
int size;
public LinList() {
//初始化头结点,让头指针指向头结点并且让当前对象指向头结点
head=current=new Node(null);
size=0;//单向链表初始长度为零
}
public void index(int i) {//定位
if(i<-1||i>size-1) {
System.out.println("参数错误");
}
if(i==-1) {//i等于负-1,头结点
return;
}
current=head.next;
int j=0;
while(current!=null&&j<i) {
current=current.next;
j++;
}
}
public void insert(int i,Object obj) {//插入
// if(i<0||i>size) {
// System.out.println("insert参数错误");
// }
index(i-1);
current.setNext(new Node(obj,current.next));
size++;
}
public void delete(int i) {//删除
if(isEmpty()) {
System.out.println("表已空,无法删除");
}
if(i<0||i>size-1) {
System.out.println("delete参数错误");
}
index(i-1);
//Object obj=current.next.getElement();
current.setNext(current.next.next);
size--;
//return obj;
}
public Object getDate(int i) {//取第i个位置上数据元素
if(i<-1||i>size-1) {
System.out.println("参数错误");
}
index(i);
Object obj=current.getElement();
return obj;
}
public int size() {
return size;
}
public boolean isEmpty() {
return size==0;
}
}
public class LinListTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
LinList l=new LinList();
//l.delete(0);
int n=10;
for(int i=0;i<n;i++) {
int temp=((int)(Math.random()*100))%100;
l.insert(i,temp);
System.out.print(temp+" ");
}
System.out.println();
System.out.println(l.size);
l.delete(4);
System.out.println("\n----删除第五个元素之后----");
for(int i=0;i<l.size;i++) {
System.out.print(l.getDate(i)+" ");
}
System.out.println();
System.out.println(l.size);
}
}
单链表反转
两种方式:递归和非递归
public class ReverseList
{
//递归法反转链表
public static Node reverselist1(Node node)
{
if(node==null||node.next==null)
{
return node;
}
else
{
Node headNode=reverselist1(node.next);
node.next.next=node;
node.next=null;
return headNode;
}
}
//遍历法反转链表
public static Node reverlist2(Node node)
{
Node pre = null;
Node next = null;
while (node != null) {
next = node.next;
node.next = pre;
pre = node;
node = next;
}
return pre;
}
public static void main(String[] args)
{
LinList l=new LinList();
int n=10;
for(int i=0;i<n;i++)
{
int temp=((int)(Math.random()*100))%100;
l.insert(i,temp);
System.out.print(temp+" ");
}
System.out.println(" ");
System.out.println(l.head.next.getElement());
// Node node1=reverselist1(l.head);
// System.out.print("反转链表后:");
// System.out.println(node1.getElement());
Node node2=reverlist2(l.head.next);
System.out.print("反转链表后:");
System.out.println(node2.getElement());
}
}