数据结构算法

顺序表

1.顺序表的插入

public int insert(int i, T x) {
		if (x == null)
			throw new NullPointerException("x==null"); // 抛出空对象异常
		if (i < 0)
			i = 0; // 插入位置i容错,插入在最前
		if (i > this.n)
			i = this.n; // 插入在最后
		Object[] source = this.element; // 数组变量引用赋值,source也引用element数组

		if (this.n == element.length) { // 若数组满,则扩充顺序表的数组容量
			this.element = new Object[source.length * 2]; // 重新申请一个容量更大的数组
			for (int j = 0; j < i; j++) // 复制当前数组前i-1个元素
				this.element[j] = source[j];
		}
		for (int j = this.n - 1; j >= i; j--) // 从i开始至表尾的元素向后移动,次序从后向前 this.element[j + 1] = source[j];

			this.element[i] = x;
		this.n++;
		return i; // 返回x序号
	}

	// 顺序表尾插入x元素,返回x序号。成员方法重载
	public int insert(T x) {
		return this.insert(this.n, x); // 插入操作中,this.n加1
	}

②练习题:
已知顺序表递减有序,将元素x插入到顺序表中,保持其有序性

public void insert1(T x){
		if(x= =null) throw new NullPointerException(“x==null);
		int t=0;
		for(int i=0;i<=n-1;i++)   // n:顺序表的长度 element[0]~element[n-1]
		  if(x>element[i]){  
		     t=i;
		     break;
		}
		if(i= =n)  t=n;
		insert(t,x);
		}

2.顺序表的删除

public T remove(int i) {// 删除第i个元素,0<=i<n,返回被删除元素。若i越界,则返回null
		if (this.n > 0 && i >= 0 && i < this.n) {
			T old = (T) this.element[i]; // old中存储被删除元素
			for (int j = i; j < this.n - 1; j++)
				this.element[j] = this.element[j + 1]; // 元素前移一个位置 this.element[this.n - 1] = null; //
														// 设置数组元素对象为空,释放原引用实例 this.n--;
			return old; // 返回old局部变量引用的对象,传递对象引用
		}
		return null;
	}

②练习题:
从顺序表中第i个元素开始连续删除k个元素的算法

	public void remove_k(int i,int k){
		if(i>0&&i+k<this.n&&this.n>0){
		for(int j=i+k;j<this.n-1;j++)
		this.element[j-k]=this.element[j];
		  }
		if(i+k>n) n=i;
		else this.n=this.n-k;
		}

单链表

1.单链表的插入

	public Node<T> insert(int i, T x) {
		if (x == null)
			throw new NullPointerException("x==null"); // 抛出空对象异常
		Node<T> front = this.head; // front指向头结点
		for (int j = 0; front.next != null && j < i; j++) // 寻找第i-1个或最后一个结点(front指向)
			front = front.next;
		front.next = new Node<T>(x, front.next);
		// 在front之后插入值为x结点,包括头插入、中间/尾插入
		return front.next; // 返回插入结点
	}

2.单链表的删除

public T remove(int i) {
		Node<T> front = this.head; // front指向头结点
		for (int j = 0; front.next != null && j < i; j++) // 遍历寻找第i-1结点(front指向)
			front = front.next;
		if (i >= 0 && front.next != null) {// 若front的后继结点存在,则删除之 T old = front.next.data; // 获得待删除结点引用的对象 front.next =
											// front.next.next; // 删除front的后继结点,包括头删除、中间/尾删除
			// 由Java虚拟机稍后释放结点占用存储单元
			return old;
		}
		return null; // 若i<0或i>表长
	}

3.单链表的遍历

Node<T>p=head;while(p!=null)
	{
		System.out.print(p.data.toString() + "");
		p = p.next;
	}

二叉树

1.二叉树的先序遍历(递归)

public void preorder() {// 输出先根次序遍历序列
		System.out.print("先根次序遍历二叉树:  ");
		preorder(this.root); // 调用先根次序遍历二叉树的递归方法 System.out.println();
	}

	private void preorder(BinaryNode<T> p) {// 先根次序遍历以p结点为根的子树,递归方法
		if (p != null) { // 若二叉树不空
			System.out.print(p.data.toString() + " ");
			// 先访问当前结点元素 preorder(p.left); //
			// 按先根次序遍历p的左子树,递归调用,参数为左孩子preorder(p.right); //
			// 按先根次序遍历p的右子树,递归调用,参数为右孩子
		}
	}

2.二叉树的中序遍历(递归)

public void inorder() {// 输出中根次序遍历序列
		System.out.print("中根次序遍历二叉树:  ");
		inorder(this.root);
		System.out.println();
	}

	private void inorder(BinaryNode<T> p) // 中根次序遍历以p结点为根的子树,递归方法	{		
		if (p != null) {			
		inorder(p.left); // 中根次序遍历p的左子树,递归调用			System.out.print(p.data.toString() + " ");			
		inorder(p.right); // 中根次序遍历p的右子树,递归调用		
		  }	
		}

3.二叉树的后序遍历(递归)

public void postorder() { // 输出后根次序遍历序
		System.out.print("后根次序遍历二叉树:  ");
		postorder(this.root);
		System.out.println();
	}

	private void postorder(BinaryNode<T> p) { // 后根次序遍历以p结点为根的子树,递归方法
		if (p != null) {
			postorder(p.left);
			postorder(p.right);
			System.out.print(p.data.toString() + " "); // 后访问当前结点元素
		}
	}

4.二叉树的先序遍历(非递归)

public void preorderTraverse(){
		System.out.print("先根次序遍历(非递归)");
		LinkedStack<BinaryNode<T>>stack=new LinkedStack<BinaryNode<T>>();
		BinaryNode<T>p=this.root;
		while(p!=null!stack.isEmpty())//p非空或栈非空
		if(p!=null){
		System.out.print(p.data+" ");//访问结点
		stack.push(p);//p结点入栈
		p=p.left;
		}
		else{  //p为空且且栈非空时
		System.out.print("# ");
		p=stack.pop();
		p=p.right;
		  }
		System.out.println();
		}

5.二叉树的中序遍历(非递归)

public void inorderTraverse(){ // 中根次序遍历二叉树的非递归算法		System.out.print("中根次序遍历(非递归):  ");		SeqStack<BinaryNode<T>> stack = new SeqStack<BinaryNode<T>>(64); // 创建一个空栈		
		BinaryNode<T> p = this.root;		
		while (p != null || !stack.isEmpty()) // p非空或栈非空时			
		if (p != null) {				
		stack.push(p); // p结点入栈				
		p = p.left; // 进入左子树			
		} 
		else {// p为空且栈非空时					
		p = stack.pop(); // p指向出栈结点				
		System.out.print(p.data + " "); // 访问结点				
		p = p.right; // 进入右子树			
		}		
		System.out.println();
			}
		}

6.×二叉树的后序遍历(非递归)

7.构造一颗二叉树的算法

	public BinaryTree(T[] prelist){ // 以标明空子树的先根遍历序列构造二叉树		this.root = create(prelist);	
	}

	// 以从i开始的标明空子树的先根序列,创建一棵以prelist[i]为根的子树,返回根结点,递归方法
	private int i = 0;

	private BinaryNode<T> create(T[] prelist) {
		BinaryNode<T> p = null;
		if (i < prelist.length) {
			T elem = prelist[i];
			i++;
			if (elem != null) { // 不能elem!="∧",因为T不一定是String p = new BinaryNode<T>(elem); // 创建叶子结点
				p.left = create(prelist); // 创建p的左子树,递归调用,实际参数与形式参数相同
				p.right = create(prelist); // 创建p的右子树,递归调用,实际参数与形式参数相同
			}
		}
		return p;
	}

8.×二叉树层次遍历

查找

1.顺序查找

public int search(T key) {
		for (int i = 0; i < this.n; i++) {
			System.out.print("查找次数:" + i + " ");
			if (key.equals(this.element[i])) {
				return i;
			}
		}
		return -1;
	}

2.二分法查找

public class SortedArray {
		public static int count = 0;
		// 统计比较次数,计算ASL成功 //
		// 已知value数组元素按升序排序,在begin~end范围内,二分法查找关键字为key元素,若查找成功返回下标,否则返回-1;
		// 若begin、end越界,返回-1。若key==null,Java抛出空对象异常。

		public static <T extends Comparable<? super T>> int binarySearch(T[] value, int begin, int end, T key) {		
		count = 0; // 统计比较次数,计算ASL成功		
		while (begin <= end) // 边界有效		{			
		int mid = (begin + end) / 2; 
		// 取中间位置,当前比较元素位置			
		System.out.print("[" + mid + "]=" + value[mid] + "?"); 
		// 显示比较中间结果,可省略			
		count++;			
		if (key.compareTo(value[mid]) == 0) // 两对象相等				
		return mid; // 查找成功			
		if (key.compareTo(value[mid]) < 0) // key对象较小				
		end = mid - 1; // 查找范围缩小到前半段			
		else				
		begin = mid + 1; // 查找范围缩小到后半段		
		}return-1; // 查找不成功
	} 
	// 已知value数组元素按升序排序,二分法查找关键字为key元素,若查找成功返回下标,否则返回-1

	public static <T extends Comparable<? super T>> int binarySearch(T[] value, T key) {
		return binarySearch(value, 0, value.length - 1, key);
	}
}

3.×分块查找

4.×在一颗二叉排序树中查找

排序

1.直接插入排序

public void insertSort() {
		for (int i = 1; i < element.length; i++) {
			int temp = (int) element[i];
			int j;
			for (j = i - 1; j >= 0 && temp < (int) element[j]; j--) {
				element[j + 1] = element[j];
			}
			element[j + 1] = temp;
			System.out.print("第" + i + "趟 temp=" + temp + "\t");
			print();
			System.out.println();
		}
	}

2.希尔排序


	public static void shellSort(int []keys){//希尔排序(升序)
		for(int delta=keys.length/2;delta>0;delta/=2){//若干趟,控制增量每趟减半

		for(int i=delta;i<keys.length;i++){//一趟分若干组,每组直接插入排序
		int temp=keys[i],j;

		for(j=i-delta;j>=0&&temp<keys[j];j-=delta)
		keys[j+delta]=keys[j];//组内直接插入排序,寻找插入位置

		keys[j+delta]=temp;
		}
		System.out.print("delta="+delta+" ");
		print(keys);
		 }
	}

3.冒泡排序

    private static void swap(int[] keys, int i, int j) {// 交换keys[i]和keys[j]的值
		int temp = keys[j];
		keys[j] = keys[i];
		keys[i] = temp;
	}

	public static void bubbleSort(int[] keys) {// 升序
		bubbleSort(keys, true);
	}

	public static void ubbleSort(int[]keys,boolean asc){
		System.out.println("冒泡排序("+(asc?"升":"降")+"序)");
		boolean=true;//是否交换的标记

		for(int i=1;i<keys.length&&exchange;i++){//有交换时再进行下一趟,最多n-1趟
		exchange=false;//假定元素未交换

		for(int j=0;j<keys.length;j++)//一趟比较,交换
		if(asc?keys[j]>keys[j+1]:keys[j]<keys[j+1]){
		swap(keys,j,j+1);
		exchange=true;//有交换
		}

		System.out.print("第"+i+"趟 ")print(keys)}

	}

4.快速排序

public static void quickSort(int[] keys){ // 快速排序(升序)
		System.out.println("快速排序(升序)");		
		quickSort(keys, 0, keys.length - 1);
    }
    // 对存于keys数组begin~end之间的子序列进行一趟快速排序,递归算法	
	private static void quickSort(int[] keys, int begin, int end) {		
	if(begin>=0&&begin<keys.length&&end>=0&&end<keys.length&&begin<end){// 序列有效
		int i = begin, j = end; // i、j下标分别从子序列的前后两端开始
		int vot = keys[i]; // 子序列第一个值作为基准值
		while (i != j) {
			while (i < j && keys[j] >= vot) // (升序)从后向前寻找较小值,不移动与基准值相等元素
				j--;
			if (i < j)
				keys[i++] = keys[j]; // 子序列后端较小元素向前移动
			while (i < j && keys[i] <= vot) // (升序)从前向后寻找较大值,不移动与基准值相等元素
				i++;
			if (i < j)
				keys[j--] = keys[i]; // 子序列前端较大元素向后移动
		}
		keys[i] = vot; // 基准值到达最终位置
		System.out.print("下标" + begin + "~" + end + ", vot=" + vot + ",  ");
		print(keys);
		quickSort(keys, begin, j - 1);
		// 前端子序列再排序,递归调用 quickSort(keys, i + 1, end); // 后端子序列再排序,递归调用
	    System.out.println();
	}
}

5.×堆排序

6.简单(直接)选择排序

public static void selectSort(int[] keys) { // 直接选择排序(升序)
		System.out.println("直接选择排序(升序)");
		for (int i = 0; i < keys.length - 1; i++) { // n-1趟排序
			int min = i;
			for (int j = i + 1; j < keys.length; j++) // 每趟在从keys[i]开始的子序列中寻找最小元素
				if (keys[j] < keys[min]) // (升序// if (keys[j]>keys[min]) //(降序) min = j; // min记住本趟最小元素下标
					System.out.print("第" + (i + 1) + "趟,下标" + i + "~" + (keys.length - 1) + ",min=" + min + ",");
			if (min != i) // 将本趟最小元素交换到前边
				swap(keys, i, min);
			print(keys);
			System.out.println();
		}

	}

	private static void swap(int[] keys, int i, int j) { // 交换keys[i]与keys[j]元素,i、j范围由调用者控制
		int temp = keys[j];
		keys[j] = keys[i];
		keys[i] = temp;
	}

7.×归并排序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值