直接插入排序是稳定的排序方法。基本思想:假设待排序的记录存放在数组R[1...n]中,初始时,R[1]自成一个有序区,无需区为R[2...n],依次将R[i]插入到当前有序区R[1...i-1]中,生成含n个记录的有序区。
void insert_sort(int a[], int n)
{
int i,j,temp;
for (i = 1; i < n; i++)
{
temp = a[i];
for (j = i - 1; i >= 0 && temp < a[j]; j--)
{
a[j + 1] = a[j];
}
a[j+1] = temp;
}
}
希尔排序算法先将要排序的一组数按某个增量d分成若干组,每组中记录的下标相差d对每组中全部元素进行排序,然后用一个较小的增量对其进行再次分组,并对每个新组重新进行排序。当增量减到1时,整个要排序的数被分成一组,排序完成 。希尔排序实质上是一种分组插入方法。
由于分组的存在,相等元素可能会分在不同组,导致它们的次序可能发生变化,因此希尔排序是不稳定的。
void shell_sort(int a[], int len)
{
int h,i,j,temp;
for (h = len / 2; h>0; h /=2)
{
for (i = h; i < len;i++)
{
temp = a[i];
for (j = i - h; j >= 0 && temp < a[j];j-=h)
{
a[j + h] = a[j];
}
a[j + h] = temp;
}
}
}
void bubble_sort(int a[], int len)
{
int temp;
for (int i = 0; i < len - 1; i++)
{
for (int j = len - 1; j > i; j--)
{
if (a[j - 1] > a[j])
{
temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
}
}
}
}
存在这样的问题,假设进行第i次扫描前,数组已经排好序,还是会进行下一次扫描,显然以后的扫描没有必要。改进程序如下:
void bubble_sort2(int a[], int len)
{
int temp,exchange;
for (int i = 0; i < len - 1; i++)
{
exchange = 0;
for (int j = len - 1; j > i; j--)
{
if (a[j - 1] > a[j])
{
temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
exchange = 1;
}
}
if (exchange != 1)
return;
}
}
采用一种分治的策略,通常称其为分治法(Divid-and-Conquer Method)。基本思想是:将原问题分解为若干个规模更小但结构与原问题相似的子问题。递归地解这些子问题,然后将这些子问题的解组合为原问题的解。设待排序的无序区为A[low...high],具体步骤:
void quick_sort(int a[], int low, int high)
{
if (low < high)
{
int i = low;
int j = high;
int pivot = a[low];
while (i < j)
{
while (i < j&&a[j] >= pivot)
j--;
if (i < j)
a[i++] = a[j];
while (i < j&&a[i] <= pivot)
i++;
if (i < j)
a[j--] = a[i];
}
a[i] = pivot; //pivot移到最终位置
quick_sort(a,low,i-1);
quick_sort(a,i+1,high);
}
}
void print_array(int a[],int len)
{
for (int i = 0; i < len; i++)
{
cout << a[i] << " ";
}
cout << endl;
}
选择排序是不稳定的。直接选择排序基本思想:n个记录的直接选择排序可经过n-1趟直接选择排序得到有序结果。
void simple_selection_sort(int a[], int len)
{
int i, j, nSmall, nIndex;
for (i = 0; i < len; i++)
{
//从a[0]开始
nSmall = a[i];
nIndex = i;
//找出i到len-1的最小值
for (j = i; j < len; j++)
{
if (a[j] < nSmall)
{
nSmall = a[j];
nIndex = j;
}
}
//最小值和初始值进行交换
a[nIndex] = a[i];
a[i] = nSmall;
}
}
node *reverse(node *head)
{
node *p1, *p2, *p3;
if (head == NULL || head->next == NULL)
return head;
p1 = head, p2 = p1->next;
while (p2)
{
p3 = p2->next;
p2->next = p1;
p1 = p2;
p2 = p3;
}
head->next = NULL;
head = p1;
return head;
}
int Str2Int(const char* str)
{
if (str == NULL)
return 0;
int num = 0;
while (str!=0)
{
num =num*10 + (*str - '0');
str++;
}
return num;
}
char Int2Str(int num)
{
char temp[1024], str[1024];
int i = 0, j = 0;
while (num)
{
temp[i] = num % 10 + '0';
i++;
num /= 10;
}
temp[i] = 0;
i -= 1;
while (i >= 0)
{
str[j] = temp[i];
j++;
i--;
}
str[j] = 0;
return str[j];
}
//考虑测试用例
//功能测试:输入正数、负数和0
//边界值测试:最大正整数、最小正整数
//特殊输入测试:输入字符串为空指针、空字符、非数字字符等
enum status{kValid=0,kInvalid};
int g_nStatus = kValid;
int Str2Int(const char* str)
{
g_nStatus = kValid;
long long num = 0;
if(str != NULL&&*str!='\0')
{
bool minus = false;
//判定=-
if (*str == '+')
str++;
else if (*str == '-')
{
str++;
minus = true;
}
//
if (*str != '\0')
{
num = Str2Int(str,minus);
}
}
return num;
}
long long Str2Int(const char* temp, bool minus)
{
long long num = 0;
while (*temp != '\0')
{
if (*temp >= '0'&&*temp <= '9')
{
int flag = minus ? -1 : 1;
num = num * 10 + (*temp - '0');
if ((!minus&&num > 0x7FFFFFFF) || (minus&&num < (signed int)0x80000000))
{
num = 0;
break;
}
temp++;
}
else
{
num = 0;
break;
}
}
if (*temp == '\0')
{
g_nStatus = kValid;
}
return num;
}
//字符串拷贝实现
char* strcpy(char* strDst, const char* strSrc)
{
assert((strDst!=NULL)&&(strSrc!=NULL));
char* temp = strDst;
while ((*strDst++ = *strSrc++) != '\0')
NULL;
return temp;
}
//微软实现
char* cdecl strcpy(char* dst, const char* src)
{
char* cp = dst;
while (*cp++ = *src++);
return dst;
}
char*类型返回值是为了实现链式表达式,返回具体值。
例如:int length=strlen(strcpy(srcDsr,"hello world"));
//Solution1
void LoopMove(char* str, int steps)
{
int n = strlen(str)-steps;
char temp[9999];
strcpy(temp,str+n);
strcpy(temp+steps,str);
*(temp + strlen(str)) = '\0';
strcpy(str,temp);
}
//Solution2
void LoopMove(char* str, int steps)
{
int n = strlen(str) - steps;
char temp[9999];
memcpy(temp,str+n,steps);
memcpy(str+steps,str,n);
memcpy(str,temp,steps);
}
//字符串中连续出现次数最多的子串
pair MaxNumofSubtrings(const string &str)
{
vector substrs;
int nMaxNum = 1, Num = 1;
string substring;
int i, len = str.length();
for (i = 0; i < len; i++)
substrs.push_back(str.substr(i,len-i));
for (i = 0; i < len; ++i)
{
for (int j = i + 1; j < len; ++j)
{
Num = 1;
if (substrs[i].substr(0, j - i) == substrs[j].substr(0, j - i))
++Num;
for (int k = j + (j - i); k < len; k += j - i)
{
if (substrs[i].substr(0, j - i) == substrs[k].substr(0, j - i))
++Num;
else
break;
}
if (Num>nMaxNum)
{
nMaxNum = Num;
substring = substrs[i].substr(0,j-i);
}
}
}
return make_pair(nMaxNum, substring);
}
string str,temp;
cout << "请输入字符串:" << endl;
cin >> str;
for (int i = str.length() - 1; i > 1; i--)
{
for (int j = 0; j < str.length(); j++)
{
if (j + i < str.length())
{
size_t t = 0, num = 0;
temp = str.substr(j,i);
t = str.find(temp);
num = str.rfind(temp);
if (t != num)
{
cout << &temp << " " << t + 1 << endl;
return 0;
}
}
}
}
测试