zoukankan      html  css  js  c++  java
  • C++常考算法

    1 strcpy,

    char * strcpy(char* target, char* source)
    {  // 不返回const char*, 因为如果用strlen(strcpy(xx,xxx)),类型不匹配。
    assert(source != NULL && target != NULL);

    char* p = target;

    while ((*target++ = *source++) != '')  // 先赋值,然后用表达式和‘’比较,最后指针加1
    ;
    return p;     // 这个算法有可能出现地址被覆盖的情况
    }

    source 拷贝的时候,就把自己的后部分给覆盖了,当source < target && soure + strlen -1 >target时候会出现这种情况。
    防止覆盖的解决方案是倒拷贝。(分两种情况处理: 正常情况,和倒着拷贝。)

    strcat

    char *Strcat(char *pszDest, const char* pszSrc)
     {char* p = pszDest;
       while(*pszDest) pszDest++; 
    while((*pszDest++ = *pszSrc++));
    return p;
    }

    2 String 的默认函数

    Mystring::Mystring(const char *str)
    {
    if (NULL == str)
    {
    m_data = new char[1];
    m_data[0] = '';
    }
    else
    {
    m_data = new char[strlen(str) + 1];
    strcpy_s(m_data,strlen(str)+1, str);
    }
    }

    Mystring::~Mystring()
    {
    delete[] m_data;
    }

    Mystring::Mystring(const Mystring &another)
    {
    m_data = new char[strlen(another.m_data) + 1];
    strcpy_s(m_data,strlen(another.m_data)+1 ,another.m_data);
    }

    const Mystring& Mystring::operator=(const Mystring &rhs)
    {
    if (this == &rhs)
    return *this;

    delete []m_data;

    m_data = new char[strlen(rhs.m_data) + 1];  
    strcpy_s(m_data,strlen(rhs.m_data) + 1,rhs.m_data);

    return *this;
    }

    3 链表逆置

    typedef struct Node

    {

        int data;

        Node *next;

    }LinkedNode, *LinkedList;

    void reversse(LinkedList  &head)

    {

            if(head == NULL ||  head->Next == NULL)

                   return;

             LinkedList p = head->next;

             LinkedList q = NULL;

             head->next = NULL;

             while(p)

               { q = q->next;

                  p->next = head;

                  head = p;

                  p = q;

               }

           head = p;

    }

    4 有序链表合并,用递归和非递归

    递归:每次从当前节点选一个进入合并的链表,对余下的再合并。

    LinkedList ListMerge(LinkedNode* p1, LinkedNode *p2)

      

      if (p1 == NULL)
        return p2;
      if (p2 == NULL)
        return p1;

           LinkedList head = NULL;

      if (p1->next < p2->next)
        { head = p1;

                    head->next   = ListMerge(p1->next,  p2);

                 }

      else
        {head = p2;

                    head->next  = ListMerge(p1,  p2->next)

                  }

      return  head;

    }

    非递归:

    LinkedList ListMerge2(LinkedNode *p1, LinkedNode *p2)

    {

    LinkedList head = NULL;

    LinkedList p = NULL;
    if (p1->data < p2->data)
    {
    head = p1;
    p1 = p1->next;
    }
    else
    {
    head = p2;
    p2 = p2->next;
    }

    p = head;

    while (p1 != NULL && p2 != NULL)
    {
    if (p1->data < p2->data)
    {
    p->next = p1; p1 = p1->next;
    }
    else
    {
    p->next = p2; p2 = p2->next;

    p = p->next;
    }

    if (p1 != NULL)
    p->next = p1;
    else
    p->next = p2;

    return head;

    }

    5 写一个函数找出一个整数数组中,第二大的数

    template<class T>

    T  secondMax(vector<T>  v)

            int max = 0;     //最大值下标

            int second = 0; // 第二大值下标     

      for (int i = 0; i < v.size; i++)
      {
        if (v[i] > v[max])
        {  max = i;
          second = max;
        }
        else if (v[i] < v[max] && v[i] > v[second])
          second = i;
    }

    reutrn second;

    }

    6 判断单链表是否有环? 如果有,环的长度?第一个环上的点在哪?

              判断有环:两个 指针,一个步长是1,另一个步长是2,如果有环的话,二者遍历会相交。

              环的长度:相交的点一定在环上,那么从这个交点开始遍历,记录遍历长度,再回来时就得到长度。

               第一个环上的点:还是找到相交的那个点,参考下一个问题的答案。

    7 判断两个链表是否有交点? 第一个交点在哪?

            判断是否相交:把其中一个链表的头尾连接,判断是否有环。

            第一个交点:   得到两个链表的长度,求得长度差K,然后长的那个先走K步,然后一起走,第一个交点就是。

     8 二分查找

    int BinarySearch(int *array, int aSize, int key)  // 从长度为aSize的数组array找到等于key的记录,array有序
    {
      if (array == NULL || aSize <= 0)
        return -1;

      int low = 0;
      int high = aSize - 1;
      int mid = 0;

      while (low <= high)
      {
        mid = (low + high) / 2;
        if (key > array[mid])
          low = mid + 1;
        else
          if (key < array[mid])
            high = mid - 1;

        else
          return mid;

      }
      return -1;
    }

    9 冒泡排序

    void bubbleSort(int *array, int len)
    {
      for (int i = 0; i < len ; i++ )
        for (int j = 0; j < len - i-1; j++)
        {
              if (array[j] > array[j + 1])
                        swap(array[j], array[j + 1]);
        }
    }

    10 直接插入排序

    void insert(int *array, int len)

    {

      for (int i = 1; i < len; i++)

                { 

                           int temp = array[i]; 

                             for(int j = i-1; j > 0; j--)

                                  {

                                           if(temp < array[]j);

                                                 array[j+1] = array[j];

                                  }

                 }

    }

    11 希尔排序

      不稳定的排序,平均时间复杂度是nlogn, 保证最后的步长是1.  直接插入排序,每次移动一个位置,希尔排序大步伐的移动。

    12 直接选择排序

      void select(int *arrya, int len)

    {   

            for (int i = 0; i < len; i++)

                 {

                     int min = array[i];

                     int index = i;

                      for(int j = i + 1; j < len; j++)

                        {     if (array[j] < min)

                                   {

                 min = array[j];

                                            index = j;

                                    }

                         }

                          if (i != index)

                                        swap(array[i], array[index]);

                 }

    }

    13 快速排序

    int  quickSort(int *array, int low, int high)

    {

             if(low == high) return;

             int begi = low;

             int end = high;

             int piv = array[low]

             while(low < high)

              {   while(high > low &&  array[high] >piv)

                               high--;

                    if (low < high) array[low] = arrray[high];

                    while(hgih > low && array[low] < piv)

                                low++;

                      if(low < high) array[high] = array[low];                   

               }

                array[low] = piv;

                quickSort(array, begin, low -1);

                quickSort(array, high-1, end); 

    }

    14   输入一个数组,实现一个函数,让所有奇数都在偶数前面:

                   答案:一次快排解决问题.

     15 归并排序

    void merge_sort(int *data, int start, int end, int *result)
    { if(end == start) return
    if (end - start == 1) //区间只有2个元素
    {
    if(data[start] > data[end])
    {
    int temp = data[start];
    data[start] = data[end];
    data[end] = temp;
    }
    }
    else // 继续进行划分
    { merge_sort(data, start, (end-star+1)/2 + start, result);
    merge_sort(data, (end-start+1)/2 + start +1, end, result);
    merge(data, start, end, result); // 把两个有序的列 归并到 result中。

    for(int i = start; i <= end; i++)
    data[i] = result[i];
    }
    }

    void merge(int *data,int start,int end,int *result) // start到end这一段中,前半部分有序,后半部分有序,
    // 归并到result中。
    {
    int left_length = (end-sart + 1)/2 +1;
    int lef_index = start;
    int right_index = start +left_length;
    int result_index = start;
    while(left_index < start + left_length && right_index < end +1)
    {
    if(data[left_index] <= data[right_index])
    resutl[result_index++] = data[left_index++];
    else
    result[result_index++] = data[right_index++];
    }

    while(left_index < start +left_lenght)
    result[result_index++] = data[left_index++];
    while(right_indx < end + 1)
    result[result_index++]=data[right_index++];
    }

     merge_sort(data,0,length-1,result);  // result是格外的存储空间

    15 堆排序

    16 前序,中序, 后序遍历二叉树的非递归

    17 KMP算法

  • 相关阅读:
    一些坑点
    [Luogu P4168] [Violet]蒲公英 (分块)
    冬令营颓废笔记
    WC2019 填坑记
    [Luogu P1829] [国家集训队]Crash的数字表格 / JZPTAB (莫比乌斯反演)
    [Luogu P2522] [HAOI2011]Problem b (莫比乌斯反演)
    [Luogu P3327] [SDOI2015]约数个数和 (莫比乌斯反演)
    [Luogu P3455] [POI2007]ZAP-Queries (莫比乌斯反演 )
    [Luogu P2257] YY的GCD (莫比乌斯函数)
    杭电 1166 敌兵布阵 (线段树)
  • 原文地址:https://www.cnblogs.com/liufei1983/p/7105189.html
Copyright © 2011-2022 走看看