数据结构与算法

1:实现单链表的逆置

2: 有个单链表,不知道节点N的值,怎样只遍历一次就可以求出中间节点?

 解:设立两个指针,比如*p, *q, p每次移动两个位置,即 p = p->next->next, q每次移动一个位置,即 q = q->next,当p到达最后一个节点时,q就是中间节点。

3:如何找出单链表中的倒数第k个元素?

  思路:设立两个指针*p,*q, p一开始指向单链表的第k个节点,q一开始指向头结点,然后p,q同时向后移动,当p移动到尾节点时,q就是我们需要找的位置。

4:一致性hash算法原理

4.1:从头到尾解析Hash表算法

5:100亿个数据中找出最大的10个?

 思路:

  1、首先一点,对于海量数据处理,思路基本上是确定的,必须分块处理,然后再合并起来。

  2、对于每一块必须找出10个最大的数,因为第一块中10个最大数中的最小的,可能比第二块中10最大数中的最大的还要大。

  3、分块处理,再合并。也就是Google MapReduce 的基本思想。Google有很多的服务器,每个服务器又有很多的CPU,因此,100亿个数分成100块,每个服务器处理一块,1亿个数分成100块,每个CPU处理一块。然后再从下往上合并。注意:分块的时候,要保证块与块之间独立,没有依赖关系,否则不能完全并行处理,线程之间要互斥。另外一点,分块处理过程中,不要有副作用,也就是不要修改原数据,否则下次计算结果就不一样了。

  4、上面讲了,对于海量数据,使用多个服务器,多个CPU可以并行,显著提高效率。对于单个服务器,单个CPU有没有意义呢?

    也有很大的意义。如果不分块,相当于对100亿个数字遍历,作比较。这中间存在大量的没有必要的比较。可以举个例子说明,全校高一有100个班,我想找出全校前10名的同学,很傻的办法就是,把高一100个班的同学成绩都取出来,作比较,这个比较数据量太大了。应该很容易想到,班里的第11名,不可能是全校的前10名。也就是说,不是班里的前10名,就不可能是全校的前10名。因此,只需要把每个班里的前10取出来,作比较就行了,这样比较的数据量就大大地减少了。

5.1 十道海量数据处理面试题与十个方法大总结

6:洗牌算法

7:堆的数据结构 比较适合处理像海量数据中找到前100个这种类似的问题

8:求两个整数的最大公约数GCM

9:二分查找

10:快速排序

11:冒泡排序

//  冒泡排序  
    public void bubbleSort() {
        for(int out = nElems - 1; out > 1; out--)
            for(int in = 0; in < out; in++ )
                if(array[in] > array[in+1])
                    swap(in, in+1);
    }

12:选择排序

// 算法思路:在这些数据中从头开始找最小的一个数,找到了就和第一个相互交换,换过之后,就代表第一个数不需要在排序了,
// 接着从第二个数开始遍历查找最小的,找到了,就和第二个位置的数交换,就这样往下循环,就可以了。
    public void selectSort() {
        int out, in, min;
        
        for(out = 0; out < nElems - 1; out++) {
            min = out;
            for(in = out + 1; in < nElems; in++)
                if(array[in] < array[min])
                    min = in;
            swap(out, min);
        }
    }

13:插入排序

 /* 插入排序:起始条件:有一个无序的数组
          比较一个数之前,先保存在一个临时值里面,
          一开始,先将数组的第二个里面的数保存在一个临时temp中,然后与数组的第一个值比较大小 a[0]与a[1],若第一个大,则交换值
          下一次循环从数组的第三个值开始比较,因为前面的是有序的了,所以先和第数组的第二个值比较大小,若a[1]>a[2],交换数值,接着和a[0]比较。所以整个插入排序就很清楚了
 */
    public void insertSort() {
        int in, out;
        
        for(out = 1; out < nElems; out++) {
            long temp = array[out];
            in = out;   //in作为标记最终插入的地方
            while(in > 0 && array[in-1] > temp) {
                array[in] = array[in-1];
                --in;
            }
            array[in] = temp;
        }
        
    }

 14:不用临时变量交换两个数的值 

int main(int argc, char *argv[])
{
    int a = 2, b = 6;

    a = a ^ b;
    b = b ^ a;
    a = a ^ b;

    printf("a = %d b = %d/n", a, b);

    return 0;
}

异或运算符^也称XOR运算符,它的规则是若参加运算的两个二进位同号,则结果为0(假);异号为1(真)。即0 ^ 0 = 0, 0 ^ 1 = 1, 1 ^ 0 = 1, 1 ^ 1 = 0 

  满足性质:    1、交换律

           2、结合律(即(a^b)^c == a^(b^c))

           3、对于任何数x,都有x^x=0,x^0=x

                       4、自反性 A XOR B XOR B = A xor  0 = A

15:怎么判断链表有环

原文地址:https://www.cnblogs.com/myseries/p/5222345.html