水仙花

一个三位数,每位的立方和相加等于这个数


void daffodilNum(){
	int x,y,z;
	for (int i = 100;i<1000;i++) {
		x = i/100;		
        y = i/10%10;	
	z = i%10;		
    if(i == x*x*x + y*y*y + z*z*z){
			printf("%4d",i);					
		}		
	}
}

连接两个字符

你可以使用自带的strcat()来实现也可以使用下面的方法


#include<stdio.h>
//连接两个字符串,这其实是连个方法用while也可以用for也可以效果是一样的
int main()
{
    char s1[100] = "one ";
    char s2[100] = "a pig";

    int i=0, j=0, n=0,k=0;

    while(s1[i] != '\0'){
        i++;
        n++;
    }
    while(s2[j] != '\0'){
        j++;
        k++;
    }
    
/*for (i = 0; s1[i] != '\0'; i++);
    n = i;
     for (j = 0; s2[j] != '\0'; j++)
    {
        s1[n] = s2[j];
        n = n + 1;
    }  */
     for (int l = 0; l < n+k; l++) {
        s1[l+n]=s2[l];

    }

    //s1[n] = '\0';


    printf("%s", s1);


}

素数

有两种方法 分别是c1 和 c2 只写出方法未写main,请自行添加并使用


//
// Created by Alitar on 2022/2/26.
//素数又称质数,除了1和其本身以外,不能被任何整数形式整除的数
//例17 17不能被2-16的任一整数整除
//
#include <stdio.h>
#include <math.h>

//法1让输入的整数与其的区间内的数一 一 相除若为0则是素数
int c1(){
    int  a = 0; //用于判断是不是素数
    int num = 0;//输入的整数

    printf("请输入一个整数:");
    scanf("%d",&num);

    for (int i = 2; i < num; i++) {
        if(num%i==0){
            a++;
        }

    }
    if(a==0){
        printf("%d是素数\n",num);
    } else{
        printf("不是素数\n",num);
    }

    return 0;

}

//法2 能被整除 其 第二个因子必定有一个小于或等于√n(你就是你的输入参数),另一个大于√n
//例16 能被 2,4,8整除 所以只需要判断2-4有无因子即可

int c2(){
    int n;//输入的整数
    int i;//循环次数
    int k;//n的平方根

    printf("请输入一个整数:");
    scanf("%d",&n);

     //sqrt()是需要double的所以要强转
    k = (int )sqrt((double )n);

    //如果完成全部循环就为素数
    for (i = 2; i < k; i++) {
        if(n%i==0){
            break;
        }
        //因为是i++ 所以是后加即i=k+1 所以i>k
       if(i>k){
           printf("%d是素数\n",n);
       }else{
           printf("不是素数\n",n);
       }
    }

}

排序

以下开始不在写main,自行添加

选择排序


//
// Created by Alitar on 2022/2/27.
//各类排序问题
//

//选择排序
//选择排序的基本算法是从待排序的区间中经过选择和交换后选出最小(最大也行卡你需求)的数值存放到 a[0] 中,
// 再从剩余的未排序区间中经过选择和交换后选出最小的数值存放到 a[1] 中,
// a[1] 中的数字仅大于 a[0],依此类推,即可实现排序。
//举个栗子{1,4,7,2,5}
//先从1开始找发现1最小所以1保持不变,得到新队列{1,4,7,2,5}
//从4开始找发现2最小所以把2换到4的位置,得到新队列{1,2,7,4,5}
//同理可得其他点

int change(){
    //使用选择排序算法排序10个数
    int i ,j,a;
    int  b[10] = {1,3,4,2,6,4,7,5,9,4};

    printf("排序前的顺序:\n");
    for (int k = 0; k <= 9; k++) {
        printf("%d",b[k]);
    }

    for (i =0; i<= 9;i++){
        for (j=i+1;j<=10;j++){
            if(b[i]>b[j]){
               a=b[i];
               b[i]=b[j];
               b[j] = a;
            }
        };

    }
    printf("\n选择排序后的顺序\n");

    for (int o = 0; o <= 9; o++) {
        printf("%d",b[o]);

    }
}

插入排序

//插入排序,其主要的实现思想是将数据按照一定的顺序一个一个的插入到有序的表中,最终得到的序列就是已经排序好的数据
// 假如有{7,6,9,3,1} 7与6比较(大于则互换位置)得到{6,7,9,3,1}
//7于9比较,不变。
//3于9比较,互换;3于7比较,互换;3与6比较互换;得到{3,6,7,9,1}
//后面的数都是同理可得自行理解
void print(int a[], int n ,int i){
    printf("%d:",i);
    for(int j=0; j<n; j++){
        printf("%d",a[j]);
    }
    printf("\n");
}
//直接插入排序函数
void InsertSort(int a[], int n)
{
    for(int i= 1; i<n; i++){
        if(a[i] < a[i-1]){//若第 i 个元素大于 i-1 元素则直接插入;反之,需要找到适当的插入位置后在插入。
            int j= i-1;
            int x = a[i];
            while(j>-1 && x < a[j]){ //采用顺序查找方式找到插入的位置,在查找的同时,将数组中的元素进行后移操作,给插入元素腾出空间
                a[j+1] = a[j];
                j--;
            }
            a[j+1] = x;      //插入到正确位置
        }
        print(a,n,i);//打印每次排序后的结果
    }
}

冒泡排序

//冒泡排序
//该算法的核心思想是将无序表中的所有记录,通过两两比较关键字,得出升序序列或者降序序列。以下以升序为基础
//假设有{3,8,7,4,2,1,3,9} 3,8比;8,7比;8,4比;8,2比;2,1(大就换位置)比以此类推直到比完得到新队列{3,7,4,2,1,3,8,9}
//得到新的队列之后通过一趟趟的比较,一个个的“最大值”被找到并移动到相应位置,直到检测到表中数据已经有序
// 或者比较次数等同于表中含有记录的个数,排序结束,

int maopap()
{
    int array[8] = {49,38,65,97,76,13,27,49};
    int i, j;
    int key;
    //有多少记录,就需要多少次冒泡,当比较过程,所有记录都按照升序排列时,排序结束
    for (i = 0; i < 8; i++){
        key=0;//每次开始冒泡前,初始化 key 值为 0
        //每次冒泡从下标为 0 开始,到 8-i 结束
        for (j = 0; j+1<8-i; j++){
            if (array[j] > array[j+1]){
                key=1;
                swap(array[j], array[j+1]);
            }
        }
        //如果 key 值为 0,表明表中记录排序完成
        if (key==0) {
            break;
        }
    }
    for (i = 0; i < 8; i++){
        printf("%d ", array[i]);
    }
    return 0;
}

希尔排序

//插入排序—希尔排序(Shell`s Sort)
//先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序
// 待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序
// 假设有{1,5,7,4,3,6,8,2}这8个数 对8(增量)除2得到缩进量4,变成{1,5,7,4}和{3,6,8,2}
//然后 1和3比,5和6比,7和8比,4和2比 (若前者大于后者则交换位置)得到新的队列{1,5,7,2,3,6,8,2}
//然后对缩进量4除2 得到 2,即2对2对的比得到①{1,5} ②{7,2}③ {3,6} ④{8,2}
//①②③④的第一个数比(1与7比若大则换位置,不大则7和3比,7比3大所以换位置,换完在和1比后面同理以此类推)直到比完为止得到新队列{1,2,3,2,7,5,8,6}
// 当仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度


void shellSort(int array[],int lenght){
   /* 希尔排序*/
    // 增量dk = n/2
    int gap, i, j, k, temp;
    // 逐步缩小增量,直到增量dk = 1
    for (gap = n/2; gap >= 1; gap /=2) {
        // 对每个子序列进行直接插入排序  共gap个组(子序列)
        // 起点变化的次数正好是等于增量
        for (i = 0; i < gap ; i++) {
            // 对每一个子序列进行直接插入排序
            for (j = i + gap; j < n; j += gap) {
                temp = a[j];
                for (k = j - gap; a[k] > temp && k >= 0; k = k - gap) {
                    a[k + gap] = a[k];
                }
                // 将其插入正确位置
                a[k + gap] = temp;
            }

        } // for
    } // for

    for (i = 0; i < 8; i++){
        printf("%d ", a[i]);
    }
}

快速排序

采用了递归的方法实现,当然你也可以选择别的方法,但都大同小异

//快速排序(Quick Sort)使用分治法策略。

//选择一个基准数,通过一趟排序将要排序的数据分割成独立的两部分;
// 其中一部分的所有数据都比另外一部分的所有数据都要小。
// 然后,再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
//假设有数组a[6]={3,4,6,1,2,5} 进行排序前要知道快速排序的基本准则,每次赋值的位置当从左往右时自动加一,从右往左时自动减一(你也可以理解成党赋值完之后这个位置
//就变为空,当下一次要赋值的时候,直接把那个值赋值在这个空的位置上就行了),
//假设a[i]与a[j],如果i>=j时就停止查找(i代表从左往右的数,j代表从右往左),使a[i]=x,然后继续从头开始排序,直到完成排序
//
//例:
//第一趟
// 从第一个数开始也就是a[0]=3 令 x=3,然后从右向左与x进行对比(小于则互换位置) ,a[4]小于x 所以a[0]=a[4](a[4]不变)
// 交换位置之后变成a[6]={2,4,6,1,2,5} 然后从左往右比找到大于x的数,a[1]大于x(i=0,j=4),则 a[4] = a[1]
//得到新的数组a[6]={2,4,6,1,4,5},继续从右往左找小于x的数,a[3]小于x(i=1 ,j =3),则 a[1]=a[3]
//得到新是数组a[6]={2,1,6,1,4,5},然后从左往右找大于x的数,a[2]大于x(i=2,j=2),则 a[3]=a[2]
//得到新的数组a[6]={2,1,6,6,4,5} 因为i=j了所以a[2]=x
//得到新的数组a[6]={2,1,3,6,4,5}
//第二趟
// 因为第一次排序的3归为,它要作为一个基准,前面为一段,后面为一段
//就变成了{{2,1},3,{6,4,5}} 
// 然后先排序前面的{2,1}在排序{6,4,5}
//然后从头开始a[0]=2 令x=2
// 重复第一趟的步骤即可
//然后再以a[3]=6 令x等于6
//重复第一趟的步骤即可
//如果要在第三趟的话步骤是一样的只需要重复第二趟的步骤即可



//a是数组,b是数组左边界,c是数组右边界
void QuickSort(int a[],int b ,int c){
    if (b < c)
    {
        int i,j,x;

        i = b;
        j = c;
        x = a[i];
        while (i < j)
        {
            while(i < j && a[j] > x) {
                j--; // 从右向左找第一个小于x的数
            }
                if (i < j) {
                    a[i++] = a[j];
                }

            while(i < j && a[i] < x){
                i++; // 从左向右找第一个大于x的数
            }
                if(i < j) {
                     a[j--] = a[i];
                 }
            }

        a[i] = x;
        QuickSort(a,b,i-1); /* 递归调用 */
        QuickSort(a,i+1, c); /* 递归调用 */
    }
    
}

//只需在主函数内定义一个数组然后使用该函数,在使用printf打印输出就行

归并排序

//归并排序
//顾名思义,就是将两个顺序序列合并成一个顺序序列的方法
//举个栗子{6,202,100,301,38,8,1}
//先分成两两一组,只剩一个就单独一组得到{6,202},{100,301},{8,38},{1}(分组之后的数列是顺序的即要么从小到大,要么从大到小)
//进行比较前两个数列和后两个数列分别进行比较得到{6,100,202,301}(比较了1次202和100);{1,8,38}(比较了2次1跟38和8)一共比较:3次;
//第二次拿{6,100,202,301}和{1,8,38},进行比较得到{{1,6,8,38,100,202,301},一共比较:4次;
//
#include <stdlib.h>
#include <stdio.h>
 
void Merge(int sourceArr[],int tempArr[], int startIndex, int midIndex, int endIndex)
{
    int i = startIndex, j=midIndex+1, k = startIndex;
    while(i!=midIndex+1 && j!=endIndex+1)
    {
        if(sourceArr[i] > sourceArr[j])
            tempArr[k++] = sourceArr[j++];
        else
            tempArr[k++] = sourceArr[i++];
    }
    while(i != midIndex+1)
        tempArr[k++] = sourceArr[i++];
    while(j != endIndex+1)
        tempArr[k++] = sourceArr[j++];
    for(i=startIndex; i<=endIndex; i++)
        sourceArr[i] = tempArr[i];
}
 
//内部使用递归
void MergeSort(int sourceArr[], int tempArr[], int startIndex, int endIndex)
{
    int midIndex;
    if(startIndex < endIndex)
    {
        midIndex = startIndex + (endIndex-startIndex) / 2;//避免溢出int
        MergeSort(sourceArr, tempArr, startIndex, midIndex);
        MergeSort(sourceArr, tempArr, midIndex+1, endIndex);
        Merge(sourceArr, tempArr, startIndex, midIndex, endIndex);
    }
}
//在main函数内调用  MergeSort(a,b,c,d)将需要排序的数组a和空数组b,以及索引位置c,结束位置d填入
//在使用for循环打印数组即可

链表

单链表

//
// Created by Alitar on 2022/3/22.
//
#include <malloc.h>
#include <stdlib.h>
#include "stdio.h"

/*
想要实现单链表的增删改查就要知道如何创建一个单链表
第一是要先定义一个结构体这个结构体内定义了所使用的单链表所需要的数据
然后就需要初始化链表
最后再main主函数内创建链表并初始化就行了
*/

//单链表

//单链表的数据结构
typedef struct Node{
    int data; //数据域
    struct Node* next;//Node的指针域
}node,*list;

//单链表初始化
list Singlelist(){

    ////创建一个节点head
    list head = (list)malloc(sizeof(node));

    //节点数据进行赋值
    //head->data=NULL;
    
    //将头节点的下一个节点设置为NULL
    if(head!=NULL){
        head->next=NULL;
    }

    return head;

}
//遍历 可以用bool写不使用void在最后return false
void search(list head)
{
    list temp = head->next;        //定义一个临时变量来指向头

    while (temp != NULL)
    {

        printf("%d ",temp->data);
        temp = temp->next; //temp指向下一个的地址 即实现++操作
    }
    printf("\n ");
}

//删除n处的节点
void FreeList(list head,int n)
{
	    list p = head,pr;
    int i= 0;


    while (i<n&&p!=NULL){//到达指定节点,此时p指向指定节点,pr指向上一节点
        pr=p;
        p=p->next;
        i++;
    }

 if(p!=NULL){   //如果p没越界
      pr->next = p->next; //将pr的下一个地址指向p后一个节点的地址
     free(p);//释放内存空间的函数
 } else{
     printf("节点不存在\n");
 }

}

//头插法加入
list addfront(list head,int n){

    list p =(list) malloc(sizeof(node));

    p->data=n;
    p->next=head->next;
    head->next=p;

    return p;
}

//尾插法插入
list addrear(list head){

    int a,b;
    node *s,*r;//r指向节点的尾指针
    int flag=1;//输入结束标志
    r=head;
    while(flag)
    {
        scanf("%int%int",&a,&b);
        if(a!=0)
        {
            s=(node*)malloc(sizeof(node));
            s->data=a;

            r->next=s;
            r=s;//尾指针换位
        }
        else
        {
            flag=0;
            r->next=NULL;
        }
    }
    return 0;

    return head;

}

//用尾差法建表
int CreatLinkList(node *l){
    int a,b;
    node *s,*r;//r指向节点的尾指针
    int flag=1;//输入结束标志
    r=l;
    while(flag)
    {
        scanf("%int%int",&a,&b);
        if(a!=0)
        {
            s=(node*)malloc(sizeof(node));
            s->data=a;

            r->next=s;
            r=s;//尾指针换位
        }
        else
        {
            flag=0;
            r->next=NULL;
        }
    }
    return 0;
}
//修改n处的节点的data,n指需要修改的节点位置,data是修改需要的数据
void changeNode(list head,int n,int data){

    list p = head;
    head=head->next;//在遍历之前,head指向首元结点
    //遍历到待更新节点
    for (int i = 1; i < n; i++) {
        head=head->next;
    }
    head->data=data;//修改数据

}


int  main(){

    list h = Singlelist();//建表并初始化

     //以头插法为例向表中依次加入10个数据
    for (int i = 0; i < 10; ++i) {
      addfront(h,i);
    }    
   //若想使用尾插法插入直接使用一下函数即可
   //输入想加入的数据,输入0退出
   // addrear(h);



    printf("---------头插法----------\n");
    search(h);//遍历就可以打印输出单链表了

    printf("--------删除第4个节点-------\n");
    FreeList(h,4);
    search(h);
    printf("--------修改第1个节点的数据域为6-------\n");
    changeNode(h,1,6);
    search(h);

}