数据结构--顺序表、链表、栈、队列、树、文件(visual studio可运行)

news2024/11/19 16:25:19

顺序表的顺序存储(增删查)

#include <stdio.h>

#include <stdlib.h>

#define MaxSize 50

typedef int ElemType;//保证顺序表可以存储任何类型

//静态分配

typedef struct{

       ElemType data[MaxSize];//定义的数组,用来存元素

       int length;//当前顺序表中有多少个元素

}SqList;

//动态分配

#define InitSize 100

typedef struct{

       ElemType *data;

       int capacity;//动态数组的最大容量

       int length;

}SeqList;

//i代表插入的位置,从1开始,e要插入的元素

bool ListInsert(SqList &L,int i,ElemType e)

{

       if(i<1||i>L.length+1)//判断要插入的位置是否合法

              return false;

       if(L.length>=MaxSize)//超出空间了

              return false;

       for(int j=L.length;j>=i;j--)//移动顺序表中的元素,从最后一位开始元素依次往后移

              L.data[j]=L.data[j-1];

       L.data[i-1]=e;//数组下标从零开始,插入第一个位置,访问的下标为0

       L.length++;

       return true;//走到这里代表插入成功,返回true

}

//删除使用元素e的引用的目的是拿出对应的值

bool ListDelete(SqList &L,int i,ElemType &e)

{

       if(i<1||i>L.length)//如果删除的位置是不合法

              return false;

       e=L.data[i-1];//获取顺序表中对应的元素,赋值给e

       for(int j=i;j<L.length;j++)//从i的位置依次把元素往前覆盖

              L.data[j-1]=L.data[j];//元素从后往前移

       L.length--;//删除一个元素,顺序表长度减1

       return true;

}

//查找成功,返回位置,位置从1开始,查找失败,返回0

int LocateElem(SqList L,ElemType e)

{

       int i;

       for(i=0;i<L.length;i++)//遍历顺序表

              if(L.data[i]==e)

                     return i+1;//加1就是元素在顺序表中的位置

       return 0;

}

//打印顺序表元素

void PrintList(SqList &L)

{

       for(int i=0;i<L.length;i++)

       {

              printf("%4d",L.data[i]);//遍历数组,要求打印到一排

       }

       printf("\n");

}

int main()

{

       SqList L;//顺序表的名称

       bool ret;//查看返回值,布尔型是True,或者False

       ElemType del;//要删除的元素

       //首先手动在顺序表中赋值

       L.data[0]=1;

       L.data[1]=2;

       L.data[2]=3;

       L.length=3;//总计三个元素

    //插入

       ret=ListInsert(L,2,60);//将顺序表传入,往第二个位置插入60这个元素

       if(ret)

       {

              printf("插入成功\n");

              PrintList(L);//调用打印函数,打印成功后的顺序表

       }else{

              printf("插入失败\n");

       }

    //删除

       ret=ListDelete(L,1,del);//把第一个位置的元素删除后存到del

       if(ret)

       {

              printf("删除成功\n");

              printf("删除元素值为 %d\n",del);

              PrintList(L); //调用打印函数,打印删除成功后的顺序表

       }else{

              printf("删除失败\n");

       }

    //查找

       ret=LocateElem(L,60);

       if(ret)

       {

              printf("查找成功\n");

              printf("元素位置为 %d\n",ret);

       }else{

              printf("查找失败\n");

       }

       system("pause");//停在控制台窗口

}

 

作业

初始化顺序表(表中元素为整形),里面元素为1,2,3通过scanf读取一个元素,插入到第二个位置,打印输出顺序表,每个元素占三个空格;然后通过scanf读取一个整型数是删除的位置。

#include <stdio.h>

#include <stdlib.h>

#define MaxSize 100

typedef int ElemType;

typedef struct {

       ElemType data[MaxSize];

       int length;

}SqList;

bool ListInsert(SqList& L, int i, ElemType e)

//不需要在子函数中改变值的时候不需要加引用&,只是将它传进去

//要不要加引用,就是看是不是在子函数中去改变主函数中对应的变量,要改就加

{

       if (i<1 || i>L.length + 1)

              return false;

       if (L.length >= MaxSize)

              return false;

       for (int j = L.length; j >= i; j--)

              L.data[j] = L.data[j - 1];

       L.data[i - 1] = e;

       L.length++;

       return true;

}

bool ListDelete(SqList& L, int i, ElemType& e)

//需要在子函数中改变值的时候才要加引用&

{

       if (i<1 || i>L.length)

              return false;

       e = L.data[i - 1];

       for (int j = i; j < L.length; j++)

              L.data[j - 1] = L.data[j];

       L.length--;

       return true;

}

void PrintList(SqList& L)

{

       for (int i = 0; i < L.length; i++)

       {

              printf("%3d", L.data[i]);

       }

       printf("\n");

}

int main()

{

       SqList L;

       bool ret_1;

       bool ret_2;

       ElemType del;

       int add_p;

       int del_p;

       scanf("%d", &add_p);//读取添加的元素值

       L.data[0] = 1;

       L.data[1] = 2;

       L.data[2] = 3;

       L.length = 3;

       ret_1 = ListInsert(L, 2, add_p);//读取的元素固定的放在第二个位置

       if (ret_1)

       {

              PrintList(L);

       }

       else {

              printf("false\n");

       }

       scanf("%d", &del_p);//读取删除元素的位置

       ret_2 = ListDelete(L, del_p, del);

       if (ret_2)

       {

              PrintList(L);

       }

       else {

              printf("false\n");

       }

}

 

//结构体指针day-01作业

输入一个学生的学号、姓名、性别,通过scanf读取后,通过printf打印输出

Input&output

101 xiongda m

#include <stdio.h>

#include <stdlib.h>

//结构体指针

struct student {

       int num;

       char name[20];

       char sex;

};//声明一个结构体类型

int main()

{

       Struct student s;

Scanf(“%d %s %c”,&s.num,s.name,&s.sex); //数组名中存的是数组的起始地址,scanf中不用加&。

Printf(“%d %s %c\n”,s.num,s.name,s,sex); //Scanf传递时,为什么后面要加一个地址,指针的传递的使用场景

       return 0;

}

//C++的引用作业

在主函数中定义字符指针char*p,在子函数中malloc申请空间,通过fgets读取字符串,然后在主函数中输出,要求子函数中使用c++的引用

#include <stdio.h>

#include <stdlib.h>

void modify_pointer(char*& p)//在子函数内操作p和主函数操作p手法一致

{

       p = (char*)malloc(100);

       fgets(p,100,stdin);//如果fgets传入的是一个指针变量,中间参数是指针指向的空间大小

}

int main()

{

       Char* p;

       Modify_pointer(p);

       Puts(p);

       return 0;

}

线性表的链式存储(重点)

#include <stdio.h>

#include <stdlib.h>

typedef int ElemType;

typedef struct LNode{

       ElemType data;

       struct LNode *next;//指向下一个结点

}LNode,*LinkList;//此处的LinkList等价于struct LNode*

//头插法新建链表(重点)

LinkList CreatList1(LinkList &L)//list_head_insert

{

       LNode *s;int x;//s为新节点

       L=(LinkList)malloc(sizeof(LNode));//带头结点的链表,不带头结点

       L->next=NULL;//L->data里边没放东西

       scanf("%d",&x);//从标准输入读取数据

       //3 4 5 6 7 9999

       while(x!=9999){

              s=(LNode*)malloc(sizeof(LNode));//申请一个新空间给s,强制类型转换

              s->data=x;//把读取到的值,给新空间中的data成员

              s->next=L->next;//让新节点的next指针指向链表的第一个元素(第一个放我们数据的元素)

              L->next=s;//指向s之后,原来的指针就断了,s作为第一个元素

              scanf("%d",&x);//读取标准输入

       }

       return L;

}

//尾插法新建链表(重点)

LinkList CreatList2(LinkList &L)//list_tail_insert

{

       int x;

       L=(LinkList)malloc(sizeof(LNode));//带头节点的链表

       LNode *s,*r=L;//r与s都是结构体指针,r代表链表表尾节点,指向链表尾部

       //3 4 5 6 7 9999

       scanf("%d",&x);

       while(x!=9999){

              s=(LNode*)malloc(sizeof(LNode));

              s->data=x;

              r->next=s;//让尾部节点指向新节点

              r=s;//r指向新的表尾结点

              scanf("%d",&x);

       }

       r->next=NULL;//尾结点的next指针赋值为NULL

       return L;

}

//按序号查找结点值

LNode *GetElem(LinkList L,int i)

{

       int j=1;

       LNode *p=L->next;//移动后指向头节点后的第一个元素a1

       if(i==0)

              return L;//查找第零个位置,则认为查找的是头节点

       if(i<1)

              return NULL;//i是负值则返回空

       while(p&&j<i)//保证p不是空指针且j<i

       {

              p=p->next;//让p指向下一个节点

              j++;

       }

       return p;

}

//按值查找(遍历链表,判断是否与e相等)

LNode *LocateElem(LinkList L,ElemType e)

{

       LNode *p=L->next;

       while(p!=NULL&&p->data!=e)

              p=p->next;

       return p;

}

//新结点e插入到第i个位置

bool ListFrontInsert(LinkList L,int i,ElemType e)

{

       LinkList p=GetElem(L,i-1);//返回为i-1,指针类型,拿到要插入位置前一个位置的地址值

       if(NULL==p)

       {

              return false;//i不对,太大或为负值

       }

       LinkList s=(LNode*)malloc(sizeof(LNode));//为新插入的结点申请空间

       s->data=e;//要插入的值放入对应的空间

       s->next=p->next;//插入步骤

       p->next=s;

       return true;

}

 

//删除第i个结点

bool ListDelete(LinkList L,int i)

{

       LinkList p=GetElem(L,i-1);//查找删除位置的前驱节点,使其指向要删除节点的后继节点,然后free要删除的节点

       if(NULL==p)

       {

              return false;//要删除的位置不对

       }

       LinkList q;

       q=p->next;//此时q指向要删除的节点

       if(NULL == q){

       return false;//要删除的位置不存在

       }

     p->next=q->next;//删除节点的前驱节点指向删除节点的后继节点,断链。

       free(q);//释放对应结点的空间

       return true;

}

//打印链表中每个结点的值

void PrintList(LinkList L)

{

       L=L->next;

       while(L!=NULL)//L等于NULL,已经访问完最后一个节点

       {

              printf("%3d",L->data);//打印当前节点数据

              L=L->next;//指向下一个节点

       }

       printf("\n");

}

//《王道C督学营》课程

//2.3 线性表的链式表示

int main()

{

       LinkList L;//链表头,是结构体指针类型

       LinkList search;//用来存储拿到的某一个节点

       CreatList1(L);//输入数据可以为3 4 5 6 7 9999(头插法)

       CreatList2(L);//输入数据可以为3 4 5 6 7 9999(尾插法)

       PrintList(L);//链表打印

       search=GetElem(L,2);//查找链表L第二个位置元素的值

       if(search!=NULL)

       {

              printf("按序号查找成功\n");

              printf("%d\n",search->data);

       }

       search=LocateElem(L,6);//按值查询

       if(search!=NULL)

       {

              printf("按值查找成功\n");

              printf("%d\n",search->data);

       }

       ListFrontInsert(L,2,99);//新结点99插入第(2)i个位置

       PrintList(L);

       ListDelete(L,4);//删除第4个结点

       PrintList(L);

       system("pause");

}

 

头插法与尾插法原理

 

双向链表(次要)

#include <stdio.h>

#include <stdlib.h>

typedef int ElemType;

typedef struct DNode{

       ElemType data;

       struct DNode *prior,*next;//前驱,后继

}DNode,*DLinkList;

//双向链表头插法

DLinkList Dlist_head_insert(DLinkList &DL)

{

       DNode *s;int x;

       DL=(DLinkList)malloc(sizeof(DNode));//带头结点的链表,DL为头节点

       DL->next=NULL;//前驱与后继都填上NULL

       DL->prior=NULL;

       scanf("%d",&x);//从标准输入读取数据

       //3 4 5 6 7 9999

       while(x!=9999){

              s=(DLinkList)malloc(sizeof(DNode));//申请一个空间空间,强制类型转换

              s->data=x;

              s->next=DL->next;//要插入的节点向后指向头节点的下一个节点:1

              if(DL->next!=NULL)//插入第一个结点时,不需要这一步操作

              {

                     DL->next->prior=s;//头节点的下一个节点向前指向要插入的节点:2

              }

              s->prior=DL;//要插入的节点指向头节点:3

              DL->next=s;//头节点指向要插入的节点:4

              scanf("%d",&x);//读取标准输入

       }

       return DL;

}

//双向链表尾插法

DLinkList Dlist_tail_insert(DLinkList &DL)

{

       int x;

       DL=(DLinkList)malloc(sizeof(DNode));//带头节点的链表

       DNode *s,*r=DL;//r代表尾指针

       DL->prior=NULL;

       //3 4 5 6 7 9999

       scanf("%d",&x);

       while(x!=9999){

              s=(DNode*)malloc(sizeof(DNode));

              s->data=x;

              r->next=s;

              s->prior=r;

              r=s;//r指向新的表尾结点

              scanf("%d",&x);

       }

       r->next=NULL;//尾结点的next指针赋值为NULL

       return DL;

}

//按序号查找结点值

DNode *GetElem(DLinkList DL,int i)

{

       int j=1;

       DNode *p=DL->next;

       if(i==0)

              return DL;

       if(i<1)

              return NULL;

       while(p&&j<i)

       {

              p=p->next;

              j++;

       }

       return p;

}

//新结点插入第i个位置

bool DListFrontInsert(DLinkList DL,int i,ElemType e)

{

       DLinkList p=GetElem(DL,i-1);//找前一个位置的地址

       if(NULL==p)

       {

              return false;

       }

       DLinkList s=(DLinkList)malloc(sizeof(DNode));//为新插入的结点申请空间

       s->data=e;

       s->next=p->next;

       p->next->prior=s;

       s->prior=p;

       p->next=s;

       return true;

}

 

//删除第i个结点

bool DListDelete(DLinkList DL,int i)

{

       DLinkList p=GetElem(DL,i-1);//删除首先要找到前一个节点

       if(NULL==p)

       {

              return false;

       }

       DLinkList q;

       q=p->next;

       if(q==NULL)//删除的元素不存在

              return false;

       p->next=q->next;//1:a指向c,断链

       if(q->next!=NULL)

       {

              q->next->prior=p;//2:c指向a。

       }

       free(q);//释放对应结点的空间

       return true;

}

//链表打印

void PrintDList(DLinkList DL)

{

       DL=DL->next;

       while(DL!=NULL)

       {

              printf("%3d",DL->data);

              DL=DL->next;

       }

       printf("\n");

}

//《龙哥带你撸代码》课程

//2.3.3 双链表增删查

int main()

{

       DLinkList DL;

       DLinkList search;

       Dlist_head_insert(DL);

       //Dlist_tail_insert(DL);

       //3 4 5 6 7 9999

       PrintDList(DL);

       search=GetElem(DL,2);

       if(search!=NULL)

       {

              printf("按序号查找成功\n");

              printf("%d\n",search->data);

       }

       DListFrontInsert(DL,3,99);

       PrintDList(DL);

       DListDelete(DL,2);

       PrintDList(DL);

       system("pause");

}

Why需要在形参的地方使用引用?

在子函数中给对应的形参赋值后,子函数结束,主函数中对应的实参发生了变化。

如果没有使用引用,在子函数中给对应的形参赋值后,子函数结束,主函数中对应的实参不会发生变化。

栈和队列-中级-day06

栈的顺序存储(简单)

#include <stdio.h>

#include <stdlib.h>

#define MaxSize 50

typedef int ElemType;

typedef struct{

       ElemType data[MaxSize];//数组

       int top;

}SqStack;

//初始化栈

void InitStack(SqStack &S)

{

       S.top=-1;//代表栈为空,初始化时-1

}

//布尔类型:用来判断栈是否为空

bool StackEmpty(SqStack &S)

{

       if(S.top==-1)

              return true;

       else

              return false;

}

 

//入栈

bool Push(SqStack &S,ElemType x)//ElemType可以指代任何数据类型

{

       If(S.top==MaxSize-1)//数组的大小不能改变,避免访问越界

//栈满:s.top=MaxSize-1,因为数组下标从零开始

       {

              return false;//栈满了,不能再入栈了

       }

       S.data[++S.top]=x;//s.top指向当前栈顶的数组下标,先自加s.top后移,x赋值给s.top

       return true;//返回true,入栈成功

}

 

//出栈

bool Pop(SqStack &S,ElemType &x)

{

       if(-1==S.top)//栈为空

              return false;

       x=S.data[S.top--];//后减减,先x=S.data[S.top];拿到栈顶元素;后S.top=S.top-1;

       return true;

}

//读取栈顶元素,返回值为布尔类型

bool GetTop(SqStack &S,ElemType &x)

{

       if(-1==S.top)//说明栈为空,s.top=0时,有一个元素

              return false;

       x=S.data[S.top];//读取栈顶元素

       return true;

}

//《王道C督学营》课程

//王道数据结构 3.1 栈

//实现栈 可以用数组,也可以用链表,我们这里使用数组

int main()

{

       SqStack S;//定义一个栈,先进后出 FILO  LIFO

       bool flag;//布尔类型:用来判断栈是否为空

       ElemType m;//用来存放拿出的元素

       InitStack(S);//初始化

       flag=StackEmpty(S);

       if(flag)

       {

              printf("栈是空的\n");

       }

       //入栈3,4,5

       Push(S,3);//入栈元素3

       Push(S,4);//入栈元素4

       Push(S,5);

       flag=GetTop(S,m);//获取栈顶元素,栈顶指针不变

       if(flag)

       {

              printf("获取栈顶元素为 %d\n",m);

       }

       flag=Pop(S,m);//弹出栈顶元素

       if(flag)

       {

              printf("弹出元素为 %d\n",m);

       }

       system("pause");

}

 

链表实现栈,用的是头部插入法,头部删除法(次要)

循环队列

循环队列原理

队尾入队,队头出队

每入一次对,rear+1

 

#include <stdio.h>

#include <stdlib.h>

#define MaxSize 5

typedef int ElemType;

typedef struct{

       ElemType data[MaxSize];//数组,存储MaxSize-1个元素,牺牲一个存储单元来区别对空与对满

       int front,rear;//队列头 队列尾

}SqQueue;

//初始化队列

void InitQueue(SqQueue &Q)

{

       Q.rear=Q.front=0;

}

//判空

bool isEmpty(SqQueue &Q)

{

       if(Q.rear==Q.front)//不需要为零

              return true;

       else

              return false;

}

//入队

bool EnQueue(SqQueue &Q,ElemType x)

{

       if((Q.rear+1)%MaxSize==Q.front) //判断是否队满

              return false;

       Q.data[Q.rear]=x;//队尾放入元素,Q.rear指向队尾元素。每入一次对,rear+1

3 4 5 6

       Q.rear=(Q.rear+1)%MaxSize;

       return true;

}

//出队

bool DeQueue(SqQueue &Q,ElemType &x)

{

       if(Q.rear==Q.front)//队列为空,不能出队

              return false;

       x=Q.data[Q.front];//先进先出

       Q.front=(Q.front+1)%MaxSize;

       return true;

}

//《王道C督学营》课程

//王道数据结构 3.2 循环队列

int main()

{

       SqQueue Q;

       bool ret;//存储返回值

       ElemType element;//存储出队元素

       InitQueue(Q);//初始化队列

       ret=isEmpty(Q);

       if(ret)

       {

              printf("队列为空\n");

       }else{

              printf("队列不为空\n");

       }

       EnQueue(Q,3);

       EnQueue(Q,4);

       EnQueue(Q,5);

       ret=EnQueue(Q,6);

       ret=EnQueue(Q,7);

       if(ret)

       {

              printf("入队成功\n");

       }else{

              printf("入队失败\n");

       }

       ret=DeQueue(Q,element);

       if(ret)

       {

              printf("出队成功,元素值为 %d\n",element);

       }else{

              printf("出队失败\n");

       }

       ret=DeQueue(Q,element);

       if(ret)

       {

              printf("出队成功,元素值为 %d\n",element);

       }else{

              printf("出队失败\n");

       }

       ret=EnQueue(Q,8);

       if(ret)

       {

              printf("入队成功\n");

       }else{

              printf("入队失败\n");

       }

       system("pause");

}

 

队列的链式存储

#include <stdio.h>

#include <stdlib.h>

typedef int ElemType;

typedef struct LinkNode{

       ElemType data;

       struct LinkNode *next;

}LinkNode;//链表节点结构体

typedef struct{

       LinkNode *front,*rear;//链表头 链表尾

}LinkQueue;//先进先出(队列的结构体)

void InitQueue(LinkQueue &Q)

{

       Q.front=Q.rear=(LinkNode*)malloc(sizeof(LinkNode));//头和尾指向申请的同一个空间结点

       Q.front->next=NULL;//头节点的Next指针为NULL

}

bool IsEmpty(LinkQueue Q)

{

       if(Q.front==Q.rear)

              return true;

       else

              return false;

}

 

 

//入队,尾部插入法

void EnQueue(LinkQueue &Q,ElemType x)

{

       LinkNode *s=(LinkNode *)malloc(sizeof(LinkNode));//给x申请空间

       s->data=x;s->next=NULL;//将x赋给s;

       Q.rear->next=s;//rear始终指向尾部

       Q.rear=s;

}

//出队  头部删除法

bool DeQueue(LinkQueue &Q,ElemType &x)

{

       if(Q.front==Q.rear) return false;//队列为空

       LinkNode *p=Q.front->next;//头结点什么都没存,所以头结点的下一个节点才有数据

       x=p->data;

       Q.front->next=p->next;//使头指针指向要删除节点的后一个节点,断链

       if(Q.rear==p)//删除的是最后一个元素

              Q.rear=Q.front;//队列置为空

       free(p);

       return true;

}

//《王道C督学营》课程

//王道考研数据结构 3.2.3 队列的链式存储

//头部删除法,尾部插入法

int main()

{

       LinkQueue Q;

       bool ret;

       ElemType element;//存储出队元素

       InitQueue(Q);//初始化队列

       //入队

       EnQueue(Q,3);

       EnQueue(Q,4);

       EnQueue(Q,5);

       EnQueue(Q,6);

       EnQueue(Q,7);

       ret=DeQueue(Q,element);

       if(ret)

       {

              printf("出队成功,元素值为 %d\n",element);

       }else{

              printf("出队失败\n");

       }

       system("pause");

}

 

作业:

#include <stdio.h>

#include <stdlib.h>

//Fib是递归函数

int Fib(int n)

{

       if(n==0)

              return 0;

       else if(n==1)

              return 1;

       else

              return Fib(n-1)+Fib(n-2);

}

//王道数据结构 斐波那契数列(每一个数都等于前两个数之和)

//递归  函数调用自身

//0  1  1  2  3   5

//f(n)=f(n-1)+f(n-2)

//考研不是很重要,了解即可

int main()

{

       int num;

       while(scanf("%d",&num)!=EOF)

       {

              printf("Fib(%d) = %d\n",num,Fib(num));

       }

       system("pause");

}

//题目  n个台阶,每次只能上1个台阶,或者2个台阶,n个台阶,有多少种走法

 

中级-day04-作业

Q:

输入3 4 5 6 7 9999一串整数,9999代表结束,通过头插法新建链表并输出;通过尾插法新建链表并输出

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#include <stdlib.h>

typedef int ElemType;

typedef struct LNode {

       ElemType data;

       struct LNode* next;//指向下一个结点

}LNode, * LinkList;

//头插法新建链表

LinkList CreatList1(LinkList& L)//list_head_insert

{

       LNode* s; int x;

       L = (LinkList)malloc(sizeof(LNode));//带头结点的链表

       L->next = NULL;//L->data里边没放东西

       scanf("%d", &x);//从标准输入读取数据

       //3 4 5 6 7 9999

       while (x != 9999) {

              s = (LNode*)malloc(sizeof(LNode));//申请一个新空间给s,强制类型转换

              s->data = x;//把读取到的值,给新空间中的data成员

              s->next = L->next;//让新结点的next指针指向链表的第一个元素(第一个放我们数据的元素)

              L->next = s;//让s作为第一个元素

              scanf("%d", &x);//读取标准输入

       }

       return L;

}

//尾插法新建链表

LinkList CreatList2(LinkList& L)//list_tail_insert

{

       int x;

       L = (LinkList)malloc(sizeof(LNode));//带头节点的链表

       LNode* s, * r = L;//LinkList s,r=L;也可以,r代表链表表尾结点,指向链表尾部

       //3 4 5 6 7 9999

       scanf("%d", &x);

       while (x != 9999) {

              s = (LNode*)malloc(sizeof(LNode));

              s->data = x;

              r->next = s;//让尾部结点指向新结点

              r = s;//r指向新的表尾结点

              scanf("%d", &x);

       }

       r->next = NULL;//尾结点的next指针赋值为NULL

       return L;

}

//打印链表中每个结点的值

void PrintList(LinkList L)

{

       L = L->next;//让L指向第一个有数据的结点

       while (L != NULL)

       {

              printf("%d", L->data);//打印当前结点数据

              L = L->next;//指向下一个结点

              if (L != NULL)

              {

                     printf(" ");

              }

       }

       printf("\n");

}

//《王道C督学营》课程

int main()

{

       LinkList L = NULL;//链表头,是结构体指针类型

       LinkList search;//用来存储拿到的某一个节点

       CreatList1(L);//输入数据可以为3 4 5 6 7 9999,头插法新建链表

       PrintList(L);//链表打印

       CreatList2(L);//输入数据可以为3 4 5 6 7 9999

       PrintList(L);

       return 0;

}

 

中级-day05-作业

Q:输入3 4 5 6 7 9999一串整数,9999代表结束,通过尾插法新建链表,查找第二个位置的值并输出,在第二个位置插入99,输出为 3 99 4 5 6 7,删除第四个位置的值,打印输出为3 99 4 5 6 7

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#include <stdlib.h>

typedef int ElemType;

typedef struct LNode {

       ElemType data;

       struct LNode* next;//指向下一个结点

}LNode, * LinkList;

//头插法新建链表

LNode* CreatList1(LinkList& L)//list_head_insert

{

       LNode* s; int x;

       L = (LinkList)malloc(sizeof(LNode));//带头结点的链表

       L->next = NULL;//L->data里边没放东西

       scanf("%d", &x);//从标准输入读取数据

       //3 4 5 6 7 9999

       while (x != 9999) {

              s = (LNode*)malloc(sizeof(LNode));//申请一个新空间给s,强制类型转换

              s->data = x;//把读取到的值,给新空间中的data成员

              s->next = L->next;//让新结点的next指针指向链表的第一个元素(第一个放我们数据的元素)

              L->next = s;//让s作为第一个元素

              scanf("%d", &x);//读取标准输入

       }

       return L;

}

//尾插法新建链表

LinkList CreatList2(LinkList& L)//list_tail_insert

{

       int x;

       L = (LinkList)malloc(sizeof(LNode));//带头节点的链表

       LNode* s, * r = L;//LinkList s,r=L;也可以,r代表链表表尾结点,指向链表尾部

       //3 4 5 6 7 9999

       scanf("%d", &x);

       while (x != 9999) {

              s = (LNode*)malloc(sizeof(LNode));

              s->data = x;

              r->next = s;//让尾部结点指向新结点

              r = s;//r指向新的表尾结点

              scanf("%d", &x);

       }

       r->next = NULL;//尾结点的next指针赋值为NULL

       return L;

}

//打印链表

void PrintList(LinkList L)

{

       L = L->next;

       while (L != NULL)//NULL是为了代表一张空的藏宝图

       {

              printf("%3d", L->data);//打印当前结点数据

              L = L->next;//指向下一个结点

       }

       printf("\n");

}

//查找第几个结点的值

LinkList GetElem(LinkList L, int i)

{

       int j = 1;

       LinkList p = L->next;//让p指向第一个结点

       if (0 == i)

       {

              return L;//i是零就返回头结点

       }

       if (i < 1)

       {

              return NULL;//i是负值就返回空

       }

       while (p && j < i)

       {

              p = p->next;//让p指向下一个结点

              j++;

       }

       return p;

}

//按值查找

LinkList LocateElem(LinkList L, ElemType e)

{

       LinkList p = L->next;

       while (p != NULL && p->data != e)

       {

              p = p->next;

       }

       return p;

}

//往第i个位置插入元素

bool ListFrontInsert(LinkList L, int i, ElemType e)

{

       LinkList p = GetElem(L, i - 1);//拿到要插入位置的前一个位置的地址值

       if (NULL == p)

       {

              return false;//i不对

       }

       LinkList s = (LinkList)malloc(sizeof(LNode));//给新结点申请空间

       s->data = e;//要插入的值放入对应空间

       s->next = p->next;//插入步骤

       p->next = s;

       return true;

}

//删除第i个位置的元素

bool ListDelete(LinkList L, int i)

{

       LinkList p = GetElem(L, i - 1);//查找删除位置的前驱节点

       if (NULL == p)

       {

              return false;//要删除的位置不存在

       }

       LinkList q = p->next;

       if (NULL == q)

       {

              return false;//要删除的位置不存在

       }

       p->next = q->next;//断链

       free(q);//释放对应结点的空间

       q = NULL;//为了避免野指针

       return true;

}

//《王道C督学营》课程

//2.3 线性表的链式表示

int main()

{

       LinkList L;//链表头,是结构体指针类型

       LinkList search;//用来存储拿到的某一个节点

       CreatList2(L);//输入数据可以为3 4 5 6 7 9999,尾插法

       search = GetElem(L, 2);//查找链表第二个位置的元素值

       if (search != NULL)

       {

              printf("%d\n", search->data);

       }

       ListFrontInsert(L, 2, 99);//新结点插入第i个位置

       PrintList(L);//链表打印

       ListDelete(L, 4);//删除第4个结点

       PrintList(L);//打印注意格式

       return 0;

}

 

中级-day06-作业(栈与队)

Q:新建一个栈,读取标准输入3个整数3 4 5,依次出栈,打印5 4 3新建循环队列(Maxsize=5),读取标准输入3 4 5 6 7,入队7时,对满,打印false,然后依次出队,输出3 4 5 6

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#include <stdlib.h>

#define MaxSize 5

typedef int ElemType;

typedef struct {

       ElemType data[MaxSize];//数组

       int top;

}SqStack;

void InitStack(SqStack& S)

{

       S.top = -1;//代表栈为空

}

//入栈

bool Push(SqStack& S, ElemType x)

{

       if (S.top == MaxSize - 1)//数组的大小不能改变,避免访问越界

       {

              return false;

       }

       S.data[++S.top] = x;

       return true;

}

//出栈

bool Pop(SqStack& S, ElemType& x)

{

       if (-1 == S.top)

              return false;

       x = S.data[S.top--];//后减减,x=S.data[S.top];S.top=S.top-1;

       return true;

}

typedef int ElemType;

typedef struct {

       ElemType data[MaxSize];//数组,存储MaxSize-1个元素

       int front, rear;//队列头 队列尾

}SqQueue;

void InitQueue(SqQueue& Q)

{

       Q.rear = Q.front = 0;

}

//入队

bool EnQueue(SqQueue& Q, ElemType x)

{

       if ((Q.rear + 1) % MaxSize == Q.front) //判断是否队满

              return false;

       Q.data[Q.rear] = x;//3 4 5 6

       Q.rear = (Q.rear + 1) % MaxSize;

       return true;

}

//出队

bool DeQueue(SqQueue& Q, ElemType& x)

{

       if (Q.rear == Q.front)

              return false;

       x = Q.data[Q.front];//先进先出

       Q.front = (Q.front + 1) % MaxSize;

       return true;

}

int main()

{

       SqStack S;//先进后出 FILO  LIFO

       bool flag;

       ElemType m;//用来存放拿出的元素

       InitStack(S);//初始化

       int i, num;

       for (i = 0; i < 3; i++)

       {

              scanf("%d", &num);

              Push(S, num);

       }

       for (i = 0; i < 3; i++)

       {

              Pop(S, m);

              printf("%2d", m);

       }

       printf("\n");

       SqQueue Q;

       InitQueue(Q);

       for (i = 0; i < 5; i++)//入队5个元素,最后一个元素不会入队成功

       {

              scanf("%d", &num);

              flag=EnQueue(Q, num);

              if (false == flag)

              {

                     printf("false\n");

              }

       }

       ElemType element;

       for (i = 0; i < 4; i++)//出队4个元素并打印每一个

       {

              DeQueue(Q, element);

              printf("%2d", element);

       }

       printf("\n");

}     

 

中级-day07-树

将任意一个节点看作根都要满足树的条件,递归。

二叉树的遍历(链式存储)

用辅助队列层次建树

 

左指针指向左孩子;右指针指向右孩子。

 

Function.h

#include <stdio.h>

#include <stdlib.h>

//作者 王道训练营 龙哥

typedef char BiElemType;

typedef struct BiTNode{

       BiElemType c;//c就是书籍上的data

       struct BiTNode *lchild;

       struct BiTNode *rchild;

}BiTNode,*BiTree;

typedef struct tag{//每一个链表中放一个树的指针

       BiTree p;//树的某一个结点的地址值

       struct tag *pnext;

}tag_t,*ptag_t;//辅助队列

//栈的相关数据结构

#define MaxSize 50

typedef BiTree ElemType;

typedef struct{

       ElemType data[MaxSize];

       int top;

}SqStack;

void InitStack(SqStack &S);

bool StackEmpty(SqStack &S);

bool Push(SqStack &S,ElemType x);

bool Pop(SqStack &S,ElemType &x);

bool GetTop(SqStack &S,ElemType &x);

//队列的相关数据结构

typedef struct LinkNode{

       ElemType data;

       struct LinkNode *next;

}LinkNode;

typedef struct{

       LinkNode *front,*rear;

}LinkQueue;

void InitQueue(LinkQueue &Q);

bool IsEmpty(LinkQueue Q);

void EnQueue(LinkQueue &Q,ElemType x);

bool DeQueue(LinkQueue &Q,ElemType &x);

Main.cpp

#include "function.h"

//递归实现

//abdhiejcfg

//前序遍历(就是深度优先遍历)

void preOrder(BiTree p)

{

       if(p!=NULL)

       {

              putchar(p->c);//等价于visit函数;上来打印当前节点,根-左-右

              preOrder(p->lchild);//递归打印,代码执行过程为每次一颗子树

              preOrder(p->rchild);

       }

}

//中序遍历  hdibjeafcg

void InOrder(BiTree p)

{

       if(p!=NULL)

       {

              InOrder(p->lchild);//左

              putchar(p->c);//根

              InOrder(p->rchild);//右

       }

}

//后续遍历//hidjebfgca

void PostOrder(BiTree p)

{

       if(p!=NULL)

       {

              PostOrder(p->lchild);//左

              PostOrder(p->rchild);//右

              putchar(p->c);//根

       }

}

//中序遍历非递归,非递归执行效率更高,考的概率很低

void InOrder2(BiTree T)

{

       SqStack S;

       InitStack(S);//初始化一个栈

BiTree p=T;//p=树根

       while(p||!StackEmpty(S))//逻辑或||

//栈不为空时为true,!StackEmpty(S)为false,p非空即可执行,两者皆空时循环结束,打印完成。

       {

              if(p)

//节点非空

              {//不断压栈,并取其左孩子

                     Push(S,p);//将p压栈

                     p=p->lchild;

              }else{

//节点为空,弹出栈中元素(弹自己)并打印,获取打印元素的右节点

                     Pop(S,p);putchar(p->c);//依次出栈,并打印该元素的右孩子

                     p=p->rchild;

              }

       }

}

//层次(层序)遍历,广度优先遍历,必须用到辅助队列

void LevelOrder(BiTree T)

{

       LinkQueue Q;//辅助队列

       InitQueue(Q);//初始化队列

       BiTree p;

       EnQueue(Q,T);//树根入队

       while(!IsEmpty(Q))//判断队列是否为空

       {

              DeQueue(Q,p);//p拿到该元素,出队当前节点并打印

              putchar(p->c);//打印

              if(p->lchild!=NULL)//左孩子不为空,左孩子入队

                     EnQueue(Q,p->lchild);

              if(p->rchild!=NULL)//右孩子不为空,右孩子入队

                     EnQueue(Q,p->rchild);

       }

}

//《王道C督学营》课程

//二叉树的建树(层次建树=完全二叉树),前序、中序、后序遍历、中序非递归遍历、层次遍历

int main()

{

       BiTree pnew;//接临时申请的空间

       int i,j,pos;

       char c;

       BiTree tree=NULL;//定义一个树根,空指针

       ptag_t phead=NULL,ptail=NULL,listpnew=NULL,pcur=NULL;//初始化指针

//phead就是队列头,ptail就是队列尾。在Function.h中。

//辅助队列:存放树的地址值

//abcdefghij

//用辅助队列层次建树:(判断phead的左右指针)

//a来,判断a的左指针是否为NULL,b来;判断a的右指针,c来,由辅助队列知,a的左右指针皆有所指,a出队,phead后移;此时判断b的左指针,放d,判断b的右指针,放e………

//树中申请空间存放数值;队列中申请空间存放指针。

       while(scanf("%c",&c)!=EOF)//读取输入元素

       {

              if(c=='\n')

              {

                     break;

              }

              pnew=(BiTree)calloc(1,sizeof(BiTNode));//calloc申请空间并对空间进行初始化,赋值为0---(树的节点分配)

              pnew->c=c;//数据放进去

              listpnew=(ptag_t)calloc(1,sizeof(tag_t));//给用链表实现的队列结点申请空间

              listpnew->p=pnew;//队列中存放a的地址

              if(NULL==tree)//根节点

              {

                     tree=pnew;//树的根

                     phead=listpnew;//队列头

                     ptail=listpnew;//队列尾

                     pcur=listpnew;

                     continue;

              }else{//左右孩子节点

                     ptail->pnext=listpnew;//新结点放入链表,通过尾插法

                     ptail=listpnew;//ptail始终指向队列尾部,有新地址时指针后移

              }//pcur始终指向要插入的结点的位置

              if(NULL==pcur->p->lchild)//如何把新结点放入树

              {

                     pcur->p->lchild=pnew;//把新结点放到要插入结点的左边

              }else if(NULL==pcur->p->rchild)

              {

                     pcur->p->rchild=pnew;//把新结点放到要插入结点的右边

                     pcur=pcur->pnext;//左右都放了结点后,pcur指向队列的下一个

              }

       }

       printf("--------前序遍历----------\n");

       preOrder(tree);

       printf("\n--------中序遍历------------\n");

       InOrder(tree);

       printf("\n--------后序遍历------------\n");

       PostOrder(tree);

       printf("\n--------中序遍历非递归------\n");//重要性低

       InOrder2(tree);

       printf("\n--------层次遍历-----------\n");

       LevelOrder(tree);

       printf("\n");

       system("pause");

}

Stack.cpp

#include "function.h"

void InitStack(SqStack &S)

{

       S.top=-1;

}

bool StackEmpty(SqStack &S)

{

       if(S.top==-1)

              return true;

       else

              return false;

}

//入栈

bool Push(SqStack &S,ElemType x)

{

       if(S.top==MaxSize-1)

       {

              return false;

       }

       S.data[++S.top]=x;

       return true;

}

//出栈

bool Pop(SqStack &S,ElemType &x)

{

       if(-1==S.top)

              return false;

       x=S.data[S.top--];

       return true;

}

//读取栈顶元素

bool GetTop(SqStack &S,ElemType &x)

{

       if(-1==S.top)

              return false;

       x=S.data[S.top];

       return true;

}

Queue.cpp

#include "function.h"

//带头结点的队列

void InitQueue(LinkQueue &Q)

{

       Q.front=Q.rear=(LinkNode*)malloc(sizeof(LinkNode));

       Q.front->next=NULL;

}

bool IsEmpty(LinkQueue Q)

{

       if(Q.front==Q.rear)

              return true;

       else

              return false;

}

void EnQueue(LinkQueue &Q,ElemType x)

{

       LinkNode *s=(LinkNode *)malloc(sizeof(LinkNode));

       s->data=x;s->next=NULL;

       Q.rear->next=s;

       Q.rear=s;

}

bool DeQueue(LinkQueue &Q,ElemType &x)

{

       if(Q.front==Q.rear) return false;

       LinkNode *p=Q.front->next;//头结点什么都没存,所以头结点的下一个节点才有数据

       x=p->data;

       Q.front->next=p->next;

       if(Q.rear==p)

              Q.rear=Q.front;

       free(p);

       return true;

}

 

二叉排序树

 

数据结构动画演示网站

 

Main.cpp

#include <stdio.h>

#include <stdlib.h>

typedef int KeyType;

typedef struct BSTNode{

       KeyType key;

       struct BSTNode *lchild,*rchild;

}BSTNode,*BiTree;

//54,20,66,40,28,79,58

//插入函数

int BST_Insert(BiTree &T,KeyType k)

{

       if(NULL==T)

       {      //为新节点申请空间,第一个节点作为树根

              T=(BiTree)malloc(sizeof(BSTNode));

              T->key=k;

              T->lchild=T->rchild=NULL;

              return 1;//代表插入成功

       }

       else if(k==T->key)//要插入的节点值与当前节点值相等

              return 0;//发现相同元素,就不插入

       else if(k<T->key) //要插入的节点值小于当前节点值,递归

              return BST_Insert(T->lchild,k);//函数调用结束后,左孩子会和原来的父亲通过引用关联起来

       else

              return BST_Insert(T->rchild,k);

}

//创建二叉排序树

void Creat_BST(BiTree &T,KeyType str[],int n)

{

       T=NULL;

       int i=0;

       while(i<n)//遍历,每一次将一个元素放入二叉排序树中

       {

              BST_Insert(T,str[i]);

              i++;

       }

}

//递归算法简单,但执行效率较低,递归实现留给大家编写

BSTNode *BST_Search(BiTree T,KeyType key,BiTree &p)//(非递归)

{

       p=NULL;//存储需要查找节点的父亲

       while(T!=NULL&&key!=T->key)

       {

              p=T;

              if(key<T->key) T=T->lchild;//比当前节点小,就左边找

              else T=T->rchild;//比当前节点大,右边去

       }

       return T;

}

//这个书上没有二叉排序树;删除节点函数

void DeleteNode(BiTree &root,KeyType x){

    if(root == NULL){

        return;//空树

    }

    if(root->key>x){//树根大于该元素

        DeleteNode(root->lchild,x);

    }else if(root->key<x){//树根小于该元素

        DeleteNode(root->rchild,x);

    }else{ //恰好查找到了删除节点

        if(root->lchild == NULL){ //左子树为空

           BiTree tempNode = root;//用临时节点存储的目的是一会要free

           root = root->rchild;//直接将其右子树上移替代root

           free(tempNode);

        }else if(root->rchild == NULL){ //右子树为空

           BiTree tempNode = root;//临时指针

           root = root->lchild; ;//直接将其左子树上移替代root

           free(tempNode);

        }else{  //左右子树都不为空

            //一般的删除策略是左子树的最大数据(左子树中不断往右查找)右子树的最小数据 代替要删除的节点(这里采用查找左子树最大数据来代替)

            BiTree tempNode = root->lchild;//当54时拿到lchild 20

            if(tempNode->rchild!=NULL){//20的右孩子不为空

                tempNode = tempNode->rchild;//拿到20的右孩子40

            }

            root->key = tempNode->key;//40的值覆盖54

            DeleteNode(root->lchild,tempNode->key);//将原来的40删除

        }

    }

}

//删除节点54

 

 

 

//删除原来的节点40

 

//删除54后最终的树

 

//中序遍历

void InOrder(BiTree T)

{

       if(T!=NULL)

       {

              InOrder(T->lchild);

              printf("%3d",T->key);

              InOrder(T->rchild);

       }

}

//《王道C督学营》课程

//二叉排序树的创建,中序遍历,查找,删除

int main()

{

       BiTree T;//树根

       BiTree parent;//存储父亲结点的地址值

       BiTree search;

       KeyType str[]={54,20,66,40,28,79,58};//将要进入二叉排序树的元素值

       Creat_BST(T,str,7);//创建二叉排序树

       InOrder(T);

       printf("\n");

       search=BST_Search(T,40,parent);//找到树中值为40的元素

       if(search)

       {

              printf("找到对应结点,值=%d\n",search->key);

       }else{

              printf("未找到对应结点\n");//没找到的时候,返回NULL

       }

       DeleteNode(T,66);//删除66这个节点

       InOrder(T);

       printf("\n");

       system("pause");

}

 

顺序查找与折半查找(二分查找)

 

 

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

typedef int ElemType;

typedef struct{

       ElemType *elem;//整型指针

       int TableLen;//存储动态数组里边元素的个数

}SSTable;

//暴力遍历

int Search_Seq(SSTable ST,ElemType key)

{

       ST.elem[0]=key;//让零号元素作为哨兵

       int i;

       for(i=ST.TableLen-1;ST.elem[i]!=key;--i);//11-1=10,

       return i;

}

//初始化元素,进行了随机数的生成

void ST_Init(SSTable &ST,int len)

{

       ST.TableLen=len+1;//多申请了一个位置,为了存哨兵

       ST.elem=(ElemType *)malloc(sizeof(ElemType)*ST.TableLen);//(10+1)*4

       int i;

       srand(time(NULL));//随机数生成

       for(i=0;i<ST.TableLen;i++)//为啥这里零号位置也随机了数据,为折半查找服务

       {

              ST.elem[i]=rand()%100;

       }

}

void ST_print(SSTable ST)

{

       for(int i=0;i<ST.TableLen;i++)

       {

              printf("%3d",ST.elem[i]);

       }

       printf("\n");

}

//时间复杂度  logn

        

 

 

 

 

 

 

//二分查找

int Binary_Search(SSTable L,ElemType key)

{

       int low=0,high=L.TableLen-1,mid;

       while(low<=high)

       {

              mid=(low+high)/2;

              if(L.elem[mid]==key)

                     return mid;//找到了

              else if(L.elem[mid]>key)//要找的值小于mid

                     high=mid-1;

              else//要找的值大于mid

                     low=mid+1;

       }

       return -1;

}

//compare函数

int compare(const void *left,const void *right)//left与right是任意两个元素的地址值

{

       return *(ElemType*)left-*(ElemType*)right;//left元素的值-right元素的值,从小到大排序

}

//《王道C督学营》课程

//顺序查找 与  折半查找

int main()

{

       SSTable ST;

       ElemType key;

       int pos;//存储查询元素的位置

       ST_Init(ST,10);//初始化10个元素

       ST_print(ST);

//顺序查找

       printf("请输入要搜索的key值:\n");

       scanf("%d",&key);

       pos=Search_Seq(ST,key);//暴力遍历

       if(pos)

       {

              printf("查找成功 位置为 %d\n",pos);

       }else{

              printf("查找失败\n");

       }

 

//二分查找:数组必须是有序的

       qsort(ST.elem,ST.TableLen,sizeof(int),compare);//qsort实现的是快排,qsort接口

// ST.elem:数组名,要排序数组的起始地址

// ST.TableLen:数组中元素的个数

// sizeof(int):每个元素所占空间的大小

// compare

       ST_print(ST);

       printf("二分查找,请输入要搜索的key值:\n");

       scanf("%d",&key);

       //有序数组

       pos=Binary_Search(ST,key);

       if(pos!=-1)

       {

              printf("查找成功 位置为 %d\n",pos);

       }else{

              printf("查找失败\n");

       }

       system("pause");

}

 

C语言文件操作

1、文件打开

 

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

int main(int argc,char *argv[])//argv[]:传进的参数以字符串形式,指针数组,指向传进来的每一个参数

{

       //printf("argc=%d\n", argc);//argc:传递了多少个参数

       //int i;

       //for (i = 0; i < argc; i++)//将每一个参数输出出来

       //{

       //    printf("%s\n", argv[i]);

       //}

       FILE* fp = fopen("file.txt", "w");//文件打开,fopen返回的是一个文件指针

//FILE* fp = fopen("file.txt", "r");//文件读取

 

//”w”:没有这个文件他会创建,有的话,他会删除里面的内容

       if (NULL == fp)

       {

              perror("fopen");

              return 0;//打开失败,程序直接结束

       }

       char c;

//读文件:用fgetc(fp)将整个文件读取出来

       //while ((c = fgetc(fp)) != EOF)//EOF为-1,为文件尾;赋值运算符的优先级低,要加个括号

       //{

       //    printf("%c", c);//打印字符

       //}

//写文件:

       //int ret;

       //ret = fputc('H', fp);

       //if (EOF == ret)

       //{

       //    perror("fopen");

       //}

       fclose(fp);//关闭文件

       return 0;

}

 

2、fread函数与fwrite函数

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

int main(int argc, char* argv[])

{

       FILE* fp = fopen("file.txt", "r+");//文件打开

       if (NULL == fp)

       {

              perror("fopen");

              return 0;

       }

       char buf[128] = { 0 };

       int ret;

       strcpy(buf, "howareyou");

       ret=fwrite(buf, sizeof(char), strlen(buf), fp);

       memset(buf, 0, sizeof(buf));//清空

       fseek(fp, 0, SEEK_SET);

       ret = fread(buf, sizeof(char), 10, fp);//因为没有去设置errno的错误码,不能使用perror

       puts(buf);

       return 0;

}

3、fread与fwrite读写整型类型

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

int main(int argc, char* argv[])

{

       FILE* fp = fopen("file.txt", "r+");//文件打开

       if (NULL == fp)

       {

              perror("fopen");

              return 0;

       }

       int i = 10;

       fwrite(&i, sizeof(int), 1, fp);

       fseek(fp, -5, SEEK_CUR);

       int j = 0;

       fread(&j, sizeof(int), 1, fp);

       printf("j=%d\n", j);

       fclose(fp);

}

中级-day11-交换/选择/插入/归并排序

 

 

 

快速排序:分治思想,不断递归,操场上一堆人,随便取一个人为分割值,比他矮站左边;比他高站右边;左右两边不断递归

#include <stdio.h>

#include <stdlib.h>

#include <time.h>//随机数接口

#include <string.h>

typedef int ElemType;

typedef struct{

       ElemType *elem;//存储元素的起始地址

       int TableLen;//元素个数

}SSTable;

//初始化函数

void ST_Init(SSTable &ST,int len)

{

       ST.TableLen=len;

       ST.elem=(ElemType *)malloc(sizeof(ElemType)*ST.TableLen);

       int i;

       srand(time(NULL));//骰子:随机数生成,每一次执行代码就会得到随机的10个元素

       for(i=0;i<ST.TableLen;i++)

       {

              ST.elem[i]=rand()%100;//摇骰子:生成的是0-99之间

       }

}

void ST_print(SSTable ST)

{

       for(int i=0;i<ST.TableLen;i++)

       {

              printf("%3d",ST.elem[i]);

       }

       printf("\n");

}

void swap(ElemType &a,ElemType &b)

{

       ElemType tmp;

       tmp=a;

       a=b;

       b=tmp;

}

// 64 94 95 79 69 84 18 22 12 78

// 12 64 94 95 79 69 84 18 22 78

//王道冒泡

void BubbleSort(ElemType A[],int n)

{

       int i,j;

       bool flag;

       for(i=0;i<n-1;i++)//i最多访问到8

       {

              flag=false;

              for(j=n-1;j>i;j--)//把最小值就放在最前面

              {

                     if(A[j-1]>A[j])

                     {

                            swap(A[j-1],A[j]);

                            flag=true;

                     }

              }

              if(false==flag)

                     return;

       }

}

//冒泡排序

void BubbleSort1(ElemType A[], int n)

{

       int i, j,flag;

       for (i=0;i<n-1;i++)//i是控制有多少个有序了

       {

              flag = 0;

              for (j = n-1; j>i;j--)//内层控制比较,交换

              {

                     if (A[j - 1] > A[j])

                     {

                            swap(A[j - 1], A[j]);

                            flag = 1;

                     }

              }

              if (0 == flag)

              {

                     break;

              }

       }

}

 

注:i用来遍历数组的下标;从3遍历到78

K:始终指向比40小的元素将要存的位置

// 64 94 95 79 69 84 18 22 12 78

//比64小的放在左边,比64大的放在右边

//王道:快速排序

//int Partition(ElemType A[],int low,int high)

//{

//    ElemType 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;

//}

//龙哥:快速排序:qsort封装好的快排接口

int Partition1(int* arr, int left, int right)

{

       int k, i;       //k记录要放入比分割值小的数据的位置

       for (i = left, k = left; i < right; i++)    //不能写成0,应该为left, 递归时会变化

       {

              if (arr[i] < arr[right])

              {

                     swap(arr[k], arr[i]);

                     k++;    //k记录要放入比分割值小的数据的位置

              }

       }

       swap(arr[k], arr[right]);

       return k;

}

int Partition(int* arr, int left, int right)

{

       int k, i;

       for (k = i = left;i<right;i++)

       {

              if (arr[i] < arr[right])

              {

                     swap(arr[i], arr[k]);

                     k++;

              }

       }

       swap(arr[k], arr[right]);

       return k;

}

//递归实现快速排序

void QuickSort(ElemType A[],int low,int high)// QuickSort(ST.elem,0,9);

{

       if(low<high)

       {

              int pivotpos=Partition(A,low,high);//分割点左边的元素都比分割点要小,右边的比分割点大

              QuickSort(A,low,pivotpos-1);//分割点左侧递归

              QuickSort(A,pivotpos+1,high);//分割点右侧递归

       }

}

//《王道C督学营》课程

//冒泡排序与快速排序

int main()

{

       SSTable ST;

       ElemType A[10]={ 64, 94, 95, 79, 69, 84, 18, 22, 12 ,78};

       ST_Init(ST,10);//初始化

       //memcpy(ST.elem,A,sizeof(A));//内存copy接口,当你copy整型数组,或者浮点型时,要用memcpy;从A copy到ST.elem,大小为sizeof(A).

       ST_print(ST);//打印排序前的数组

       //BubbleSort1(ST.elem,10);//冒泡排序

       QuickSort(ST.elem,0,9);

       ST_print(ST);//打印排序后的数组

       system("pause");

}

中级-插入排序

 

插入排序:无序依次插入到有序中;

1有序,后边无序

1、2有序(2插入1),后边无序

1、2、3有序(3插入到1、2),后边无序

。。。。。//插入排序:哨兵:存放将要插入有序组的元素(每次先放后比)

从后往前遍历有序序列,比哨兵大的往后覆盖,比哨兵小的不用动,最后空位放哨兵。

 

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

typedef int ElemType;

typedef struct{

       ElemType *elem;//整型指针

       int TableLen;

}SSTable;

void ST_Init(SSTable &ST,int len)

{

       ST.TableLen=len+1;//实际申请11个元素的空间

       ST.elem=(ElemType *)malloc(sizeof(ElemType)*ST.TableLen);

       int i;

       srand(time(NULL));

       for(i=0;i<ST.TableLen;i++)

       {

              ST.elem[i]=rand()%100;//随机了11个数,但是第一个元素是没有用到的

       }

}

void ST_print(SSTable ST)

{

       for(int i=0;i<ST.TableLen;i++)

       {

              printf("%3d",ST.elem[i]);

       }

       printf("\n");

}

//插入排序,从小到大排序,升序

void InsertSort(ElemType A[],int n)

{

       int i,j;

       //24 66 94  2 15 74 28 51 22 18  2

       for(i=2;i<=n;i++)//第零个元素是哨兵,第一个元素自然有序;从第二个元素开始拿,往前面插入

       {

              if(A[i]<A[i-1])

              {

                     A[0]=A[i];//放到暂存位置,A[0]即是暂存,也是哨兵

                     for(j=i-1;A[0]<A[j];--j)//移动元素,从后往前;内层循环控制有序序列中的每一个元素和要插入的元素(哨兵)比较

                            A[j+1]=A[j];

                     A[j+1]=A[0];//把暂存元素插入到对应位置

              }

       }

}

//折半查找 插入排序

void MidInsertSort(ElemType A[],int n)

{

       int i,j,low,high,mid;

       for(i=2;i<=n;i++)

       {

              A[0]=A[i];

              low=1;high=i-1;

              while(low<=high)//先通过二分查找找到待插入位置

              {

                     mid=(low+high)/2;

                     if(A[mid]>A[0])

                            high=mid-1;

                     else

                            low=mid+1;

              }

              for(j=i-1;j>=high+1;--j)

                     A[j+1]=A[j];

              A[high+1]=A[0];

       }

}

//希尔排序 

//多轮插入排序,考的概率很低,因为编写起来复杂,同时效率并不如快排,堆排

void ShellSort(ElemType A[],int n)

{

       int dk,i,j;

       // 73 29 74 51 29 90 37 48 72 54 83

       for(dk=n/2;dk>=1;dk=dk/2)//步长变化

       {

              for(i=dk+1;i<=n;++i)//以dk为步长进行插入排序

              {

                     if(A[i]<A[i-dk])

                     {

                            A[0]=A[i];

                            for(j=i-dk;j>0&&A[0]<A[j];j=j-dk)

                                   A[j+dk]=A[j];

                            A[j+dk]=A[0];

                     }

              }

       }

}

//《王道C督学营》

int main()

{

       SSTable ST;

       ST_Init(ST,10);//实际申请了11个元素空间

       ST_print(ST);

       InsertSort(ST.elem,10);

       //MidInsertSort(ST.elem,10);

       //ShellSort(ST.elem,10);

       ST_print(ST);

       system("pause");

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/124809.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MergeTree写入查询流程分析

基础概念回顾 前面几节我们分别详细分析了分区&#xff0c;索引&#xff0c;数据存储相关原理&#xff0c;这些组件配合在一起给Clickhouse数据库带来非常高效的查询性能。前面的文章也单独介绍了这几个组件。接下来&#xff0c;就分别从写入过程、查询过程&#xff0c;以及数…

数字孪生水电站,三维组态助力发电流程优化

从大禹治水到三峡大坝的建造&#xff0c;人类为控制和调配自然界的地表水和地下水&#xff0c;修建了许多的水利工程。对水资源进行了广泛的开发利用&#xff0c;诸如农业灌溉、工业和生活用水、水力发电、航运、港口运输、淡水养殖、旅游等。 将图扑软件与 GIS、粒子仿真、虚拟…

在re:Invent 2022大会打球、喝酒?没错!

编辑&#xff5c;阿冒虽然距离去拉斯维加斯参加亚马逊云科技re:Invent 2022大会&#xff0c;差不多已经过去了一个月&#xff0c;不过时不时仍有熟稔的朋友来问我&#xff0c;你在展区球场上如何如何&#xff0c;巴拉巴拉……为啥他们对我的行动如此了解&#xff1f;其实&#…

effective C++读书笔记

目录 用const,enum,inline去替换#define 尽可能去使用const 确保对象使用前已被初始化 这是effective C中的第一大章节&#xff1a;让自己习惯c 用const,enum,inline去替换#define 当用使用这样的代码&#xff1a; #define ASPECT RATIO 1.653 记号名称ASPECT RATIO可能未…

图像风格迁移---基于多适应网络的任意风格传输

ABSTRACT 任意风格转换是一个具有研究价值和应用前景的重要课题。给定一个内容图像和引用的风格绘画&#xff0c;一个所需的风格转换将使用风格绘画的色彩色调和生动的笔画模式渲染内容图像&#xff0c;同时保持详细的内容结构信息。风格迁移方法首先学习内容和内容和风格引用…

推荐系统的矩阵分解

0 序言 推荐系统中基于内容的协调过滤算法通过用户之间的相似性或者物品之间的相似性&#xff0c;通过相似性来为用户做决策和推荐&#xff1b;基于内容的协调过滤算法在实际生产环境中&#xff0c;User或Item的数据量非常大&#xff08;百万级别&#xff09;&#xff0c;存储…

操作系统期末考试必会题库3——处理机调度

1、假设一个系统中有5个进程&#xff0c;它们处于就绪状态的时刻和估计运行时间如下表所示&#xff0c;忽略I/O以及其它开销时间&#xff0c;若分别按先来先服务&#xff0c;最短进程优先&#xff0c;最短剩余时间优先、响应比优先、时间片轮转&#xff08;时间片&#xff1d;1…

世界杯 | 其实世界杯结束之前,卡塔尔就开拆体育场了...

大家好&#xff0c;这里又是建模助手。 世界杯已经圆满落幕&#xff0c;梅老板满载而归&#xff0c;但阿根廷与法国的这场世界杯决赛注定载入史册&#xff0c;成为永恒经典&#xff0c;或许将会是世界杯历史上最精彩的决赛之一。 &#xff08;梅老板捧起大力神杯那一刻&#x…

人工鱼群算法参数寻优及可视化(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 人工鱼群优化算法是一种基于模拟鱼群行为的优化算法&#xff0c;是由李晓磊等在2002年提出的一种新型的寻优算法。人工鱼群主要…

黑马Hive+Spark离线数仓工业项目--数仓事实层DWB层构建(1)

整体目标&#xff1a;构建数仓中的DWB&#xff1a;主题事务事实表 核心的主题事实的构建&#xff1a;SQL实现 主题的指标 原始事务事实数据【DWD】&#xff1a;订单数据 主题事务事实数据【DWB】&#xff1a;订单主题 - 主题周期快照事实表&#xff1a;数据应用层【ST&#…

一场4800亿“锂电”战事,瑞浦兰钧射出三支“价值之箭”

顺势而为&#xff0c;是一家企业成功突围的最佳利器。 如今&#xff0c;几乎所有企业都被“碳达峰碳中和”的国家级战略所影响。在此大势的推动之下&#xff0c;锂离子电池、清洁能源等产业也随之进入高速发展期。工信部数据显示&#xff0c;上半年全国锂离子电池产量超过280G…

HNU编译原理实验二cminus_compiler-2022-fall

前言&#xff1a;个人感觉比第一次的难&#xff0c;借鉴了前辈的报告才勉强看懂在干嘛 lab2实验报告实验要求 本次实验需要先将自己的 lab1 的词法部分复制到 /src/parser 目录的 lexical_analyzer.l并合理修改相应部分&#xff0c;然后根据 cminus-f 的语法补全 syntax_analy…

3.3 直接耦合放大电路

工业控制中的很多物理量均为模拟量&#xff0c;如温度、流量、压力、液面、长度等&#xff0c;它们通过各种不同传感器转化成电量后也均为缓慢变化的非周期性信号&#xff0c;而且比较微弱&#xff0c;因而这类信号一般均需通过直接耦合放大电路后才能驱动负载。 一、直接耦合…

二叉树,红黑树,B树、B+树的区别

树的概念 树的演变 二叉搜索树 二叉搜索树可以提高查询效率&#xff0c;左小右大&#xff0c;但是他不好掌握根节点的数字是哪个&#xff0c;容易一边倒&#xff0c;导致层数变多&#xff0c;降低效率 平衡二叉搜索树 平衡二叉搜索树在二叉搜索树的基础上,通过控制任意一个节…

Shell“语言程序设计基础......“

Shell语言也有设计基础吗?...... 没有所谓的语言程序设计基础往往是一种就是菜鸡互啄的一种状态......哦,据说当年,发明笔记本电脑的人(想出发明笔记本电脑这个创意的人)一开始的工作是写说明书的Linux 或者 Unix 发明的那个年代应该还没有这种充满了营销的或者应试的表述方法…

密码学 密钥管理

密钥管理 出发点&#xff1a;在一种安全策略指导下的密钥产生&#xff0c;存储&#xff0c;分配&#xff0c;删除&#xff0c;归档和应用方案。 目的&#xff1a;维持系统各实体之间的密钥关系&#xff0c;抗击各种威胁&#xff1a; 1.密钥泄露 2.密钥和公钥身份真实性丧失 3…

计算机内存机制精讲

全文目录1、一个程序在计算机中到底是如何运行的&#xff1f;2、虚拟内存到底是什么&#xff1f;虚拟地址中间层思想3、虚拟地址空间以及编译模式CPU的数据处理能力编译模式32位编译模式64位编译模式4、内存对齐&#xff0c;提高寻址效率5、内存分页机制&#xff0c;完成虚拟地…

react-native学习过程记录

1、关于react-native init 创建项目报错 cli.init is not a function 问题解决 直接采用npx react-native init chapter2 --version 0.68.2 创建项目&#xff08;即指定version&#xff09; 参考地址&#xff1a;https://blog.csdn.net/qq_42231156/article/details/126396576…

【云原生进阶之容器】第二章Controller Manager原理剖析--2.1节Controller Manager综述

1 K8S Controller Manager原理解析 1.1 Controller Manager作用简述 一般来说,智能系统和自动系统通常会通过一个“操作系统”不断修正系统的工作状态。在Kubernetes集群中,每个Controller都是这样的一个"操作系统",它们通过APIServer 提供的(List-Watch)接口实…

小程序集成Three.js开发常见问题

1.加载模型后开发者工具卡顿 我想很多小伙伴都遇到过这个问题&#xff0c;网上很多方法&#xff0c;说什么清缓存&#xff0c;清内存&#xff0c;基本作用都不大。在不断的摸索中&#xff0c;我逐渐找到了一些解决的办法&#xff0c;希望对你有帮助。 (1) 截至发文时间&#…