1.
2 .
算法最终要编译成具体的计算机指令
每一个指令,在具体的计算机 cpu上运行的时间是固定的
通过具体的n的步骤的多少就可以推导出算法的复杂度
3.
1)判断一个算法的效率时,往往只需要关注操作数量的最高次项,其他次项和常数项可以忽略
2)在没有特殊说明时,我们所分析的算法时间复杂度都是指最坏时间复杂度
4 .
在一个由自然数1-1000中某些数字所组成的数组中,每个数字可能出现零次或煮多次。设计一个算法,找出出现次数最多的数完。
//空间换时间
#include <stdio.h>
#include <stdlib.h>
void search(int arr[], int len)
{
int sp[1000] = { 0 };
for (int i = 0; i < len; i++)
{
int index = arr[i] - 1;
sp[index]++;
}
int max = 0;
for (int i = 0; i < 1000; ++i)
{
if (max < sp[i])
{
max = sp[i];
}
}
for (int i = 0; i < 1000; ++i)
{
if (max == sp[i])
{
printf("出现次数最多的数: %d 总共: %d\n", i+1, sp[i]);
}
}
}
int main()
{
int arr[] = { 1, 1, 3, 4, 5, 6, 6, 6, 2, 3 };
search(arr, sizeof(arr) / sizeof(arr[0]));
system("pause");
return 0;
}
5.全封装
线性表顺序存储
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
typedef void SeqList; //顺序表指针
typedef void SeqListNode; //节点指针
typedef struct _tag_Seqlist
{
int length;
int capacity;
unsigned int *node; // ---> int*[capacity]
}TSeqList;
typedef struct Teacher
{
int age;
char name[7];
}Teacher;
SeqList* SeqList_Create(int capacity); //创建表
void SeqList_Destroy(SeqList* list); //销毁表
void SeqList_Clear(SeqList* list); //清空表
int SeqList_Length(SeqList* list); //表的当前容量
int SeqList_Capacity(SeqList* list); //表的最大容量
int SeqList_Insert(SeqList* list,SeqListNode* Node,int pos); //指定位置插入
SeqListNode* SeqList_Get(SeqList* list, int pos); //指定位置获取表中的元素
SeqListNode* SeqList_Delete(SeqList* list, int pos); //指定位置删除表中的元素
#include "seqlist_head.h"
SeqList* SeqList_Create(int capacity)
{
TSeqList *tmp = (TSeqList*)malloc(sizeof(TSeqList));
assert(tmp != NULL);
memset(tmp, 0, sizeof(TSeqList));
tmp->node = (unsigned int*)malloc(sizeof(unsigned int*)*capacity);
assert(tmp->node != NULL);
tmp->capacity = capacity;
tmp->length = 0;
return tmp;
}
void SeqList_Destroy(SeqList* list)
{
assert(list != NULL);
TSeqList* tlist = (TSeqList*)list;
free(tlist->node);
tlist->node = NULL;
free(tlist);
tlist = NULL;
}
void SeqList_Clear(SeqList* list)
{
assert(list != NULL);
TSeqList*tlist = (TSeqList*)list;
tlist->length = 0;
}
int SeqList_Length(SeqList* list)
{
assert(list != NULL);
TSeqList*tlist = (TSeqList*)list;
return tlist->length;
}
int SeqList_Capacity(SeqList* list)
{
assert(list != NULL);
TSeqList*tlist = (TSeqList*)list;
return tlist->capacity;
}
int SeqList_Insert(SeqList* list, SeqListNode* Node, int pos)
{
assert(list != NULL && Node != NULL&& pos >= 0);
TSeqList*tlist = (TSeqList*)list;
if (tlist->length >= tlist->capacity)
{
printf("fun SeqList_Insert error\n");
return -1;
}
//容错
if (pos > tlist->length)
{
pos = tlist->length;
}
//元素后移
for (int i = tlist->length; i > pos; --i)
{
tlist->node[i] = tlist->node[i - 1];
}
tlist->node[pos] = (unsigned int)Node;
tlist->length++;
return 0;
}
SeqListNode* SeqList_Get(SeqList* list, int pos)
{
assert(list != NULL);
TSeqList*tlist = (TSeqList*)list;
return (SeqListNode*)tlist->node[pos];
}
SeqListNode* SeqList_Delete(SeqList* list, int pos)
{
assert(list != NULL && pos >= 0);
TSeqList*tlist = (TSeqList*)list;
SeqListNode*tmp = (SeqListNode*)tlist->node[pos];
for (int i = pos + 1; i < tlist->length; ++i)
{
tlist->node[i - 1] = tlist->node[i];
}
tlist->length--;
return tmp;
}
int main()
{
Teacher t1, t2, t3, t4, t5;
t1.age = 31;
t2.age = 32;
t3.age = 33;
t4.age = 34;
t5.age = 35;
SeqList *list = SeqList_Create(10);
SeqList_Insert(list, (SeqListNode*)&t1, 0);
SeqList_Insert(list, (SeqListNode*)&t2, 0);
SeqList_Insert(list, (SeqListNode*)&t3, 0);
SeqList_Insert(list, (SeqListNode*)&t4, 0);
SeqList_Insert(list, (SeqListNode*)&t5, 0);
for (int i = 0; i < SeqList_Length(list); i++)
{
Teacher*tmp = (Teacher*)SeqList_Get(list, i);
printf("%d ", tmp->age);
}
printf("\n");
getchar();
while (SeqList_Length(list) > 0)
{
SeqList_Delete(list, 0);
}
printf("%d\n", SeqList_Length(list));
system("pause");
return 0;
}
6.
优点: 无需为线性表中的逻辑关系增加额外的空间
可以快速的获取表中合法位置的元素
缺点: 插入和删除操作需要移动大量元素
当线性表长度变化较大时难以确定存储空间的容量