大端和小端
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h> // malloc
// 大小端模式判断;小端模式: 一个数据的低位字节数据存储在低地址
// int *强制类型转换为char *,用“*”解引用 为啥强制类型转化char*
// p为指向char类型的数据指针,char类型数据正好一个字节,因此*p解引用出来是一个字节;*p == 0x12
void test04(int c)
{
char* p = (char*)&c;
//int* p = &c;
//printf("%d\n", *p);
if (*p == 0x12)
printf("Big endian.\n");
else if (*p == 0x78)
printf("Little endian.\n");
else
printf("Uncertain.\n");
}
/* 当前是使用小端模式存储,0x78这一个字节存储在低位,把他移动到高位上去*/
void test03()
{
int b = 0x12345678;
int result = 0;
int size = sizeof(b);
while (size--)
{
result |= ((b & 0xFF) << (size * 8));// b & 0xFF = 78(可以使用计算器计算)
b >>= 8;
}
}
int main()
{
//test04();//Little endian.
//printf("%x\n", c);
test03();
return 0;
}
顺序表
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define MAXLISTSIZE 1024 // 宏定义顺序表中最大容量
/*
typedef struct的作用
1、简化较复杂的声明
2、typedef并没有创建一个新的类型,而是为某个已经存在的类型增加一个新的名字,如示例中的linearlist是 struct的别名
typedef struct // 此处省略了结构的的名称 为匿名结构体 typedef struct line
{
int id;
char name;
}linearlist
使用与不使用typedef的区别
1、使用typedef声明结构体,可以省略struct这个关键字
linearlist list[3];
2、不使用typedef声明结构,则不可以省略struct这个关键字
struct linearlist list[3];
*/
typedef struct // 结构体
{
int data[MAXLISTSIZE]; // 顺序表
int last; // 顺序表元素个数
}Linearlist; // linearlist 结构体别名
void ListList(Linearlist* list) // 打印线性顺序表 声明一个指针 list 指向结构体linearlist首地址
{
int i; // 定义变量i
printf("当前线性表的状态\n"); // 提示语句
if (list->last == 0) // 条件判断 顺序表为空
printf("当前线性表为空\n"); // 如果添加成立 则输出当前语句
else // 如果条件不成立 则遍历数组
for (i = 0; i < (list->last); i++) // 循环遍历顺序表
printf("[%4d]", list->data[i]); // 输出元素
printf("\n"); // 打印一个换行符
}
void Output(Linearlist* list) // 打印说明文档
{
system("cls"); // 清理屏幕
printf("- 顺序表 -\n");
printf("- a:追加一个节点 i:插入一个节点 -\n");
printf("- d:删除一个节点 e:退出 -\n ");
ListList(list); // 打印线性顺序表
}
Linearlist* CreateList() // 创建线性顺序表
{
Linearlist* list = (Linearlist*)malloc(sizeof(Linearlist)); // 分配空间
list->last = 0; // 初始化节点值
return list; // 返回初始化头节点指针
}
void AppendNode(Linearlist* list, int n)
{
if (list->last < MAXLISTSIZE) // 顺序表不溢出
{
list->data[list->last] = n; // 初始化节点值
list->last += 1;
}
}
void insertNode(Linearlist* list, int n, int pos) //插入节点
{
int j;
if (pos < 0 || pos > list->last) // || 逻辑或运算 | 位运算 或 只要一个pos<0 pos>list->last中一个成立就行
printf("所插入的位置超出顺序表的范围\n");
else
{
for (j = list->last; j >= pos; j--) // 逆向遍历顺序表
list->data[j + 1] = list->data[j]; // 元素后移
list->data[pos] = n; // 指向节点赋值
list->last++; // 顺序表长度加1
}
}
void DeleteNode(Linearlist* list, int pos) // 删除节点
{
int j;
if ((pos < 0) || (pos > list->last)) // 删除位置超出顺序表的范围
printf("所要删除的位置超出顺序表的范围\n");
else
{
for (j = pos; j < list->last; j++) // 遍历顺序表
list->data[j] = list->data[j + 1]; // 元素前移
list->last--; // 顺序长度减一
}
}
int main() // 主函数
{
int key, pos; // 整型变量
char ch; // 字符型变量
Linearlist* list; //
list = CreateList(); // 创建顺序列表
while (1)
{
Output(list);
printf("请选择:");
ch = getchar(); // 接受选项
fflush(stdin); // 清除缓存
if (ch == 'a') // 追加
{
printf("请输入要追加的数据");
scanf("%d", &key);
AppendNode(list, key);
}
else if (ch == 'i') // 插入
{
printf("请输入要插入的数据的位置:");
scanf("%d", &pos);
printf("请输入要插入的数据");
scanf("%d", &key);
insertNode(list, key, pos);
}
else if (ch == 'd') // 删除
{
printf("请输入要删除的数据的位置");
scanf("%d", &pos);
DeleteNode(list, pos);
}
else if (ch == 'e') // 退出
exit(0);
Output(list);
fflush(stdin); // 清除缓存
}
return 0;
}
单链表
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h> // 头文件 stdio 就是指 “standard input & output"(标准输入输出)
#include <stdlib.h> /* stdlib.h里面定义了五种类型、一些宏和通用工具函数,常用的函数如malloc()、calloc()、realloc()、free()、system()、atoi()、atol()、rand()、srand()、exit()*/
struct linknode // 链表结构声明
{
int data; // 存储结点数据
struct linknode* next; // 指向下一个结点
};
typedef struct linknode LinkNode; // 为结构体定义新类型
/*链表函数*/
LinkNode* CreatLinkNode() // 创建链表函数
{
int i; // 整型变量i
LinkNode* head, * ptr, * p; // 链表结点 head指向链表的首地址 head=null或head=0时 链表为空
head = (LinkNode*)malloc(sizeof(LinkNode)); // 分配内存
if (!head) // 判断条件
{
printf("内存分配失败!\n"); // 打印提示语句
exit(1); // 退出
}
printf("请输入第1个数据:");
scanf("%d", &head->data); // 创建结点内容
head->next = NULL; // 初始化该结点指向的下一个结点为空
ptr = head; // ptr指向链表开始
for (i = 1; i < 5; i++) // 循环创建结点
{
p = (LinkNode*)malloc(sizeof(LinkNode));
// 获取linknode在内存中所占的字节的长度,用malloc函数开辟出保存linknode所占内存的一段地址,
//并强制转换为struct linknode类型指针
if (!p)
{
printf("内存分配失败!\n");
exit(1);
}
printf("请输入第%d个数据:", i + 1);
scanf("%d", &p->data);
p->next = NULL;
ptr->next = p; // 链接结点
ptr = ptr->next; // 指向下一个结点
}
return head;
}
/*链表的遍历*/
LinkNode* FindNode(LinkNode* head, int num) //
{
LinkNode* ptr;
ptr = head; // 指向链表起始
while (ptr != NULL) // 遍历链表
{
if (ptr->data == num) return ptr; // 查找编号
ptr = ptr->next;//
/*如果当前节点的数据值等于目标数值 num,那么就返回当前节点 ptr。
如果当前节点的数据值不等于目标数值 num,那么将指针 ptr 移动到下一个节点。*/
}
return ptr;
}
/*链表结点的插入模块*/
LinkNode* insertNode(LinkNode* head, LinkNode* ptr, int value) //
{
LinkNode* newnode = (LinkNode*)malloc(sizeof(LinkNode)); // 分配内存
if (!newnode) return NULL;
newnode->data = value; // 创建结点内容
newnode->next = NULL; // 设置指针初值
if (ptr == NULL)
{
newnode->next = head;
return newnode;
}
else
{
if (ptr->next == NULL) ptr->next = newnode;// 是否是链表结束
else
{
newnode->next = ptr->next; // 新结点指向下一个结点
ptr->next = newnode;
}
}
return head;
}
/* 链表结点删除*/
LinkNode* DeleteNode(LinkNode* head, LinkNode* ptr) // 定义自定义类型LinkNode的两个形参指针head,ptr 指向 LinkNode结构体
{
LinkNode* pre; // 指向前一个结点
if (ptr = head) // 是否用链表的开始
return head->next; // 输出第2个结点
else
{
pre = head;
while (pre->next != ptr)
pre = pre->next;
if (ptr->next = NULL) // 是否是链表结束 删除最后一个节点
pre->next = NULL; // 最后一个节点的结构指针指向NULL
else
pre->next = ptr->next; // 删除中间结点 ;删除当前的自己,连接前面的pre->next 和 自己后面的 ptr->next;
}
free(ptr); // 释放结点内存
return head;
}
/*链表输出模块*/
void PrintNode(LinkNode* ptr)
{
while (ptr != NULL) // 指针ptr非空
{
printf("%d\t", ptr->data); // 输出当前指针指向结点的数据
ptr = ptr->next; // 指针向后移动指向下一个结点
}
printf("\n"); // 打印一个换行符
}
/*链表的内存释放*/
void FreeLinkNode(LinkNode* head) // 定义LinkNode类型的head指针指向结构体LinkNode的首地址
{
LinkNode* ptr;
while (head != NULL)
{
ptr = head;
head = head->next; //指针向后移动指向下一个结点
free(ptr);
}
}
int main()
{
int num, value;
LinkNode* head, * ptr; // 定义结构体自定义数据类型LinkNode的指针 head ptr
head = CreatLinkNode();
PrintNode(head);
printf("输入要查找的数据:\n");
scanf("%d", &num);
ptr = FindNode(head, num); // 查询数据
if (!ptr)
printf("没有找到\n");
else
{
printf("找到啦!\n请输入要插入的数据:\n");
scanf("%d", &value);
head = insertNode(head, ptr, value);// 插入数据
PrintNode(head);
}
printf("请输入要查找并删除的数据:\n");
scanf("%d", &num);
ptr = FindNode(head, num);
if (!ptr)
printf("没有找到\n");
else
{
printf("找到了!\n");
head = DeleteNode(head, ptr); // 删除
PrintNode(head);
}
FreeLinkNode(head);
return 0;
}
C字符串
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h> // malloc
void test01()
{
char a[10]= "COPY";
char* str = "Hello"; // const char* str = "Hello";
printf("字符串P:%p\n", str);// 00D17B30
printf("字符串S:%s\n", str);// Hello
/*printf("字符串C:%c\n", str);*/ //ERROR
/* 可以看到,str[]和 *str 是一样的*/
/* str为指针,联想到数组,[]进行遍历*/
printf("字符串C:%c\n", str[0]);// H
printf("字符串C:%c\n", str[1]);// e
printf("字符串D:%d\n", str[0]);// 72
printf("字符串C:%c\n", *str);// H
printf("字符串C:%c\n", *(str + 1));// e
printf("字符串D:%d\n", *str);// 72
}
字符串getchar
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
/*
int main()
{
int N = 1;
while (getchar() != 'y')
printf("Number: %d\n", N++);
return 0;
}*/
int main()
{
int N = 1;
while (getchar() != 'y')
{
printf("Number: %d\n", N++);
// 开始检测第二个键盘输入的数字;发现是Enter,直接到大循环;发现不是Enter,进入continue,返回大循环
// 因此都是回到大的while循环,而没有接着检测缓冲区里面的第三个 第四个数字
while (getchar() != '\n')
continue;
if (getchar() == 'e')
{
printf("EXIT");
break;
}
}
return 0;
}
排序(插入排序、冒泡排序、快速排序、简单选择排序)
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
// 插入排序算法 递增排序
/*
1.从第一个元素开始,该元素可以认为已经被排序
2.取下一个元素tem,从已排序的元素序列从后往前扫描
3.如果该元素大于tem,则将该元素移到下一位
4.重复步骤3;
5.tem插入到该元素的后面,如果已排序所有元素都大于tem,则将tem插入到下标为0的位置
6.重复步骤2~5
*/
void InsertSort(int arr[], int n)
{
int i, j,temp;
for (i = 1; i < n; i++)
{
arr[i] < arr[i - 1];// 后一个元素小于前一个元素
temp = arr[i]; // 先保存一下
for (j = i - 1; (j>=0) & (arr[j] > temp); j--) // 下面开始依次比较
{
arr[j + 1] = arr[j]; // 所有大于temp的元素都向后挪
}
arr[j + 1] = temp; // j-- 退出循环
}
}
// 希尔排序
/*
1.先选定一个小于N的整数gap作为第一增量,然后将所有距离为gap的元素分在同一组,
并对每一组的元素进行直接插入排序。然后再取一个比第一增量小的整数作为第二增量,重复上述操作…
2.当增量的大小减到1时,就相当于整个序列被分到一组,进行一次直接插入排序,排序完成。
*/
// 对A[]数组共n个元素进行希尔排序
void ShellSort(int A[], int n) {
int d, i, j;
for (d = n / 2; d >= 1; d = d / 2) { //步长d递减
for (i = d + 1; i <= n; ++i) {
if (A[i] < A[i - d]) {
A[0] = A[i]; //A[0]做暂存单元,不是哨兵
for (j = i - d; j > 0 && A[0] < A[j]; j -= d)
A[j + d] = A[j];
A[j + d] = A[0];
}
}
}
}
// 冒泡排序
/*
算法思路:从后往前(或从前往后)两两比较相邻元素的值,若为逆序(即 A[i-1]>A[i]),
则交换它们,直到序列比较完。如此重复最多 n-1 次冒泡就能将所有元素排好序。为保证稳定性,关键字相同的元素不交换。
*/
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void BubbleSort(int A[], int n)
{
int i,j;
for (i = 0; i < n - 1; i++)
{
bool flag = false;
for (j = n - 1; j > i; j--)
{
if (A[j] < A[j - 1]) //后一个元素小于前一个元素
{
swap(&A[j], &A[j - 1]);//交换
flag = true;
}
}
if (flag == false)
return 0; //若本趟遍历没有发生交换,说明已经有序
}
}
//快速排序
// 用第一个元素将数组A[]划分为两个部分
int Partition(int A[], int low, int high) {
int pivot = A[low];
while (low < high) {
while (low < high && A[high] >= pivot)
--high;
A[low] = A[high];
while (low < high && A[low] <= pivot)
++low;
A[high] = A[low];
}
A[low] = pivot;
return low;
}
// 对A[]数组的low到high进行快速排序
void QuickSort(int A[], int low, int high) {
if (low < high) {
int pivotpos = Partition(A, low, high); //划分
QuickSort(A, low, pivotpos - 1);
QuickSort(A, pivotpos + 1, high);
}
}
// 简单选择排序
//算法思路:每一趟在待排序元素中选取关键字最小的元素与待排序元素中的第一个元素交换位置。
// 对A[]数组共n个元素进行选择排序
void SelectSort(int A[], int n) {
for (int i = 0; i < n - 1; i++) { //一共进行n-1趟,i指向待排序序列中第一个元素
int min = i;
for (int j = i + 1; j < n; j++) { //在A[i...n-1]中选择最小的元素
if (A[j] < A[min])
min = j;
}
if (min != i)
swap(&A[i], &A[min]);
}
}
int main() {
int arr[6] = { 1,4,4,6,5,25 };
//InsertSort(arr, 6);// 插入排序算法;
//BubbleSort(arr, 6); // 冒泡排序;
//QuickSort(arr, 0,5); //快速排序
SelectSort(arr, 6);// 简单选择排序
for (char i = 0; i < 6; i++)
printf("%d\n", arr[i]);
return 0;
}
查找(顺序查找(线性表)、二分查找(顺序表))
线性表(顺序表和单链表)
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h> // malloc
#define InitSize 10 // 顺序表的初始长度
typedef struct {
int* data; // 声明动态分配数组的指针
int Tablen; //声明动态分配数组长度
}mydata;
//顺序查找 ST查找表 key为关键字
int Search_Seq(mydata ST, int key)
{
int i;
for (i = 0; i < ST.Tablen && ST.data[i] != key; ++i);
// 查找成功返回数组下标,否则返回-1
return i == ST.Tablen ? -1 : i;
}
// 二分查找 折半查找:⼜称“⼆分查找”,仅适⽤于有序的顺序表。(顺序表拥有随机访问 的特性,链表没有)
// 折半查找
int Binary_Search(mydata ST, int key)
{
int low = 0, high = ST.Tablen, mid;
while (low <= high) {
mid = (low + high) / 2;
if (ST.data[mid] == key)
return mid;
else if (ST.data[mid] > key)
high = mid - 1; //从前半部分继续查找
else
low = mid + 1; //从后半部分继续查找
}
return -1;
}
int main() {
mydata DATA;
// 用malloc函数申请一片连续的存储空间
DATA.data= (int*)malloc(InitSize*sizeof(int));// 10 x 4 = 40 Byte
DATA.Tablen = 8;
for (int i = 0; i < DATA.Tablen; i++)
{
DATA.data[i]= i; // 指针遍历,填充数据
}
for(int i = 0; i < DATA.Tablen; i++)
printf("%d\n", DATA.data[i]);
// 顺序查找
int location1 = Search_Seq(DATA, 3); // 在DATA里面查找3在哪里
printf("顺序查找——位置在: %d\n", location1);
// 二分查找
int location2 = Binary_Search(DATA, 3); // 在DATA里面查找3在哪里
printf("二分查找——位置在: %d\n", location2);
return 0;
}
算法题目:
1.题目要求:数列的定义如下: 数列的第一项为n,以后将此为前一项的平方根,求数列的前m项的和。
#include<stdio.h>
#include<math.h>
int main()
{
int n,i;
double m,a,s=0;
while(scanf("%lf %d",&m,&n)!=EOF)
{
for(i=0;i<n;i++)
{
s=s+m;
(double)m=sqrt((double)m);//因为最后输出要保留两位小数所以要把m定义为浮点型
}
printf("%0.2lf\n",s);
s=0;
}
return 0;
}