算法:
通俗定义:
解题的 方法 和 步骤。
狭义的定义:
对存储数据的操作。
广义的定义:
泛型
泛型: 无论 数据是 如何存储,我们对该数据的操作都是一样的。
我们至少可以通过 两种 数据结构 来存储数据
数组
优点: 存取速度快 缺点: 需要一个连续很大的内存 插入和删除元素的效率很低
链表
优点: 插入元素效率高 不要一个连续很大的内存 缺点: 查找某个位置的元素 效率低
数据结构:
如何将 现实中 复杂的问题,转化为 计算机中的数据 进行存储。
// 定义了一个链表节点的数据类型
struct Node{
int data;
struct Node * pNext;
};
int main(void){
return 0;
}
确定一个链表需要1个参数就可以
头指针 就可以了
#includestruct Node{ int data; struct Node * pNext; }; struct Node * CreateList(){ return pHead; } int main(void){ struct Node * pHead; // pHead指针 用来存放 链表头结点的地址 pHead = CreatList(); TraverseList(pHead); return 0; }
完整版 链表
#include总结#include #include struct Node{ int data; // 数据域 struct Node * pNext; // 指针域 }; struct Node * CreateList(void){ int len; // 用来存放有效节点的个数 int i; int val; // 用来临时存放用户输入的结点的值 // 分配了一个不存放有效数据的头结点 struct Node * pHead = (struct Node *)malloc(sizeof(struct Node)); struct Node * pTail = pHead; pTail->pNext = NULL; printf("请输入您需要生成的链表节点的个数: len = "); scanf("%d", &len); for (i = 0; i < len; ++i) { printf("请输入第%d个节点的值: ", i+1); scanf("%d", &val); struct Node * pNew = (struct Node *)malloc(sizeof(struct Node)); if (NULL == pNew) { printf("分配失败,程序终止!n"); exit(-1); } pNew->data = val; pTail->pNext = pNew; pNew->pNext = NULL; pTail = pNew; } return pHead; } bool EmptyList(struct Node * pHead){ if (pHead->pNext == 0) { // pHead->pNext等价于 (*pHead).pNext return true; } else{ return false; } } void TraverseList(struct Node * pHead){ struct Node * p = pHead->pNext; if (EmptyList(pHead)) { printf("链表为空!n"); } while (p!= NULL) { printf("%dn", p->data); p = p->pNext; } return; } int main(void){ struct Node * pHead; // pHead指针 用来存放 链表头结点的地址 pHead = CreateList(); //CreatList功能:创建一个非循环 单链表,并将链表 头结点 地址 返还给pHead TraverseList(pHead); // 把每个元素都输出 return 0; }
狭义算法:
算法是 依附于 存储结构的
不同的 存储结构,所执行的算法是不一样的!
广义算法:
广义的算法也叫泛型
无论数据是如何存储的,对该数据的操作都是一样的。
即 站在更高的维度,数组 和 链表 都是线性结构
都是 输出 第一个元素,第二个元素,第三个元素,这样。
& 按位与 && 叫 逻辑与 也叫并且 | 按位或 || 叫 逻辑或 ^ >> <<
#include#include #include int main(void) { int i = 5; int j = 7; int k; k = i & j; // 0101 // 0111 // 0101 是5 printf("%dn",k); // 5 k = i && j; printf("%dn",k); // k的值只能是1或0,因为&&是逻辑运算符。逻辑运算符的结果只能是 真 或 假。 // 1 return 0; }
#include#include #include int main(void) { int i = 5; int j = 7; int k; k = i | j; // 0101 // 1101 // 1101 结果为7 // 1|0 = 1 // 1|1 = 1 // 0|1 = 1 // 0|0 = 0 printf("%dn",k); // 7 k = i || j; printf("%dn",k); // k的值只能是1或0,因为&&是逻辑运算符。逻辑运算符的结果只能是 真 或 假。 // 1 return 0; }
按位取反
int main(void)
{
int i = 5;
int j = 7;
int k;
k = ~i; // ~i: 把i变量所有的二进制取反
printf("%dn",k); // -6
k = i || j;
printf("%dn",k); // k的值只能是1或0,因为&&是逻辑运算符。逻辑运算符的结果只能是 真 或 假。 // 1
return 0;
}
int main(void)
{
int i = 5;
int j = 7;
int k;
k = i ^ j;
// 1001
// 1011
// 0010
printf("%dn",k); // 2
k = i || j;
printf("%dn",k); // k的值只能是1或0,因为&&是逻辑运算符。逻辑运算符的结果只能是 真 或 假。 // 1
return 0;
}
int main(void)
{
int i = 5;
int j = 7;
int k;
k = i << 2;
printf("%dn",k); // 5 x 4 = 20
k = i || j;
printf("%dn",k); // k的值只能是1或0,因为&&是逻辑运算符。逻辑运算符的结果只能是 真 或 假。 // 1
return 0;
}
左移
int main(void)
{
int i = 5;
int j = 7;
int k;
k = i << 2; // 把i的所有二进制位左移2位,右边补零
printf("%dn",k); // 5 x 4 = 20
return 0;
}
int main(void)
{
int i = 5;
int k;
k = i >> 2; // 把i的所有二进制位右移2位,左边补零
printf("%dn",k); // 5 ➗ 4 = 1
return 0;
}
位运算负的现实意义:
通过位运算符我们可以对数据的操作精确到每一位



