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

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

}

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

  1. 常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构)

    常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构) 数据结构和算法作为程序员的基本功,一定得稳扎稳打的学习,我们常见的框架底层就是各类数据 ...

  2. 黑马程序员 C语言数据结构与算法之线性表(链表/栈/队列/顺序表)

    C语言 链表基础知识清晰讲解(黑马) 讲的蛮好,就是音质不太好,有时听不清讲的啥! [黑马]数据结构与算法之线性表(链表/栈/队列/顺序表)[配套源码 嘛蛋,看错了,这是java的... 文章目录 链 ...

  3. 数据结构-线性表之用队列实现栈用栈实现队列

    文章目录 **********用队列实现栈 一:思路 二:实现 (1)结构体定义 (2)初始化和销毁 (3)进"栈" (4)出"栈" 三:代码 ******** ...

  4. C语言链表的转置算法,c语言编程集 数据结构 顺序表 点链表 数制转换 矩阵转置.doc...

    c语言编程集 数据结构 顺序表 点链表 数制转换 矩阵转置 #include "stdio.h" #include "malloc.h" /*typedef s ...

  5. 面试必备:高频算法题汇总「图文解析 + 教学视频 + 范例代码」必问之 链表 + 栈 + 队列 部分!

    链表 链表是最基本的数据结构,面试官也常常用链表来考察面试者的基本能力,而且链表相关的操作相对而言比较简单,也适合考察写代码的能力.链表的操作也离不开指针,指针又很容易导致出错. 综合多方面的原因,链 ...

  6. python顺序表数组_数据结构 | 顺序表

    什么是数据结构? 数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成. 简单来说,数据结构就是设计数据以何种方式组织并存储在计算机中. 比如:列表.集合与字典等都 ...

  7. Educoder头歌数据结构顺序表及其应用

    头歌实践平台答案educoder 数据结构-顺序表及其应用 第1关:顺序表的实现之查找功能 /***************************************************** ...

  8. 数据结构-顺序表(动态分配存储空间)

    数据结构-顺序表(动态分配存储空间) (1)顺序表的结构定义: 结构型定义:(动态分配存储空间) /*** 动态分配存储空间*/ #define InitSize 100 //动态分配存储空间时,不限 ...

  9. C语言/C++常见习题问答集锦[八十三]之数据结构顺序表(operand types are error: no match for “operator==“)

    C语言/C++常见习题问答集锦[八十三]之数据结构顺序表{operand types are error: no match for "operator=="} 程序之美 前言 主 ...

  10. 线性表→顺序表→链表 逐个击破

    一. 线性表 1. 前言 线性表,全名为线性存储结构.使用线性表存储数据的方式可以这样理解,即 " 把所有(一对一逻辑关系的)数据用一根线儿串起来,再存储到物理空间中 ".这根线有 ...

最新文章

  1. 2018/8/26 PSO-based Clustering Techniques to Solve Multimodal Optimization Problems: A Survey
  2. python命令大全-深度学习中python常用命令
  3. 使用命令将单个java文件打包为jar
  4. Spring IOC 容器源码分析 - 循环依赖的解决办法
  5. golang函数:命名返回值代码示例
  6. GDCM:gdcm::IPPSorter的测试程序
  7. 表达式求值负数乘负数_为什么现在很多期权的时间价值都为负数?
  8. Bootstrap开发框架视频整理
  9. Java并发编程中volatile实现过程详细解析
  10. 【Breadth-first Search 】785. Is Graph Bipartite?
  11. Kafka的配置文件详细描述
  12. 信息学奥赛一本通 1012:计算多项式的值 | OpenJudge NOI 1.3 07
  13. python 多分类 recall_sklearn多分类问题
  14. 串口485接法图_485串口接线
  15. Mac系统如何安装Eclipse并搭建Android开发环境
  16. itunes store服务中断_Apple目前正在经历App Store iTunes Store和Mac App Store的中断
  17. vue下个人实现拼图验证码
  18. 程序员口中常说的API是什么意思?什么是API?
  19. C语言中##和#的作用
  20. 实验六 移位寄存器及其应用

热门文章

  1. JQuery 中 AJAX 如何实现 Excel 文件 下载
  2. 《Windows CE嵌入式开发入门——基于Xscale架构》第2章 系统时钟
  3. 2022-2027年中国机器人伺服电机行业发展前景及投资战略咨询报告
  4. NSAT-2000三极管自动测试系统
  5. 计算机二级不参加会记入诚信档案吗,考生必看!弃考会被记入诚信档案吗?
  6. python中in什么意思_python中5in什么意思
  7. selinum自动化测试代码编写框架
  8. HUAWEI 擎云L420 折腾记 (搭建arm gcc、openocd 雅特力 MCU开发环境)
  9. 520浪漫情人节可爱少女风格PPT模板
  10. 【自学考试】计算机操作系统概论02323 2017年版大纲