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

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

#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");

}

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无处安放的小曾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值