常见数据结构题

1.链表逆序输出

必然需要遍历,并且只知道头指针,并且不破坏源链表结构;既然逆序,那么容易想到后进先出,很容易的想到堆栈;

堆栈的基本操作:

std::stack<int>value;

value.push(parameter);

value.top()

value.pop();

或者采用这种方法,Head->Node1->Node2->Node3->....->NodeN;

第一次交换节点1和节点2,变成,Head->Node2->Node1->Node3->....->NodeN;

第二次交换节点2和节点3,变成,Head->Node3->Node2->Node0->....->NodeN;

.......

struct Node *p2 = Head->next;

	while(p2->next !=NULL){
		struct Node *q = p2->next;
		p2->next = q->next;
		q->next=Head->next;
		Head->next = q;

	}


2.O(1)时间内删除链表

如果给定一个链表的头指针和指向一个节点的指针,要求删除该节点指针指向的节点;

 一般而言,如果要删除一个节点,我们需要找到该节点的上一个节点,使该节点的上一个节点的指针,指向该节点的下一个节点;

而如果按照这种思想,必须遍历;

换种思路,其实不需要遍历;

如下图:需要删除i节点,

我们可以将其后的j节点的值赋给i节点,之后i的指针指向j的后面的节点;

(i位于结尾,或者链表只含有一个节点,需要特殊处理)

3.链表的倒数第K个节点

可以使用两个指针,一个指向链表头,一个指向距离链表头节点k-1的节点;同时后移,当第二个指针到达尾部,第一个指针所指即为所指;

4.链表逆序

5.合并两个排序的链表

6.两个链表的第一个公共节点

如果两个链表有节点重合,那么它们的拓扑一定是Y形状的,而不可能是X形状的。

两种方法,一种是使用两个栈,遍历,将两个链表的元素入栈,然后依次出栈,遇到第一个不相同的节点,返回;

一种是,首先遍历两个链表,设置两个指针,将较长的链表先提前走两个链表的差值,之后一起向后遍历,遇到第一个相同的节点返回;

7.链表操作注意点

链表末尾指针记得赋空值;

8.快排

static void quick_sort1(int s[], int l, int r) {
		if (l < r) {
			int i = AdjustArray(s, l, r);// 先成挖坑填数法调整s[]
			quick_sort1(s, l, i - 1); // 递归调用
			quick_sort1(s, i + 1, r);
		}
	}

	static int AdjustArray(int array[], int left, int right) // 返回调整后基准数的位置
	{
		int flagNum = array[left]; // s[l]即s[i]就是第一个坑
		while (left < right) {
			// 从右向左找小于x的数来填s[i]
			while (left < right && array[right] >= flagNum)
				right--;
			if (left < right) { //注意这里,必须加判断,才能确保是因为 前面条件 s[j] >= x 不成立,才跳出while循环的。
				array[left] = array[right]; // 将array[right]填到array[left]中,array[right]就形成了一个新的坑
				left++; //注意这里为什么是 i++, 而不是 j--; 因为i马上会移到下一个位置,而j需要保持现在的位置,记录交换之后的位置;
			}
			// 从左向右找大于或等于x的数来填s[j]
			while (left < right && array[left] < flagNum)
				left++;
			if (left < right) {
				array[right] = array[left]; // 将s[i]填到s[j]中,s[i]就形成了一个新的坑
				right--;
			}
		}
		// 退出时,i等于j。将x填到这个坑中。
		array[left] = flagNum;
		return left;
	}
9.归并排序

static void mergeSort(int array[], int left, int right, int temp[]){
		if (left < right){ //
			int middle = (left + right)/2;
			mergeSort(array, left, middle, temp);
			mergeSort(array, middle + 1, right, temp);
			merge(array, left, middle, right, temp);
		}
	}
	static void merge(int array[], int left, int middle, int right, int temp[]){
		int i = left, j = middle;
		int l = middle + 1, m = right;
		int k = 0;
		while (i <= j && l <= m){
			if(array[i] >= array[l])
				temp[k++] = array[l++];
			else
				temp[k++] = array[i++];
		}
		
		while(i <= j) //
			temp[k++] = array[i++];
		
		while(l <= m)//
			temp[k++] = array[l++];		
		for (i = 0; i < k; i++){
			array[left + i] = temp[i];
		}
	}

10.二分查找

static boolean search(int array[], int left, int right, int value){
		
		if (left <= right){
		int middle = (left + right)/2;
		if (array[middle] == value)
			return true;
		else if(array[middle] > value)
			return search(array, left, middle - 1,value);
			
		else
			return search(array, middle + 1, right,value);
		}
		return false;
	}

11.连续子数组最大值

static int maxSummary(int array[], int length){
		int max = 0;
		int current = 0;
		
		for(int i = 0; i < length; i++){
			current = current + array[i];
			
			if(current <= array[i])
				current = array[i];
			if(current < current - array[i]){
				max = current - array[i];
			}								
		}				
		return max;
	}

分析:时间复杂度O(n),意味着只需要遍历一次,不能使用枚举法

思想,例,1,-2,3,10,-4,7,2,-5;首先把1放到当前总和中,current为1;

之后把-2加到current中,current为-1,-1小于原先的current :1,因此当前的max为:1

再把3加入current,current为2, 2小于当前值3,因此,将current记为当前值,3;

再把10加入到current,current为13;

再把-4加入到current,current为9,9小于原先的13,因此max为13,;

。。

12. 调整数组中奇数偶数的位置,使奇数位于偶数之前。

public static void main(String[] args) {
		int[] array = {1,2,3,4,5};
		adjustArray(array);
	}
	
	public static void adjustArray(int[] array){
		int length = array.length;
		int left = 0;
		int right = length - 1;
		int temp = 0;
	
		
		while(left < right){
			while(left < right){
				if(array[right]%2 != 0)
					break;
				else
					right--;
			}
			
			while(left < right){
				if(array[left]%2 == 0)
					break;
				else
					left++;
			}
			
			temp = array[right];
			array[right] = array[left];
			array[left] = temp;
			
			left++;
			right--;
			
		}
		
		
		
		for(int i = 0;i < array.length;i++)
			System.out.println(array[i]);
	}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值