数据结构与算法

数据结构与算法

数据结构(英语:data structure)是计算机中存储、组织数据的方式。
数据结构是一种具有一定逻辑关系,在计算机中应用某种存储结构,并且封装了相应操作的数据元素集合。它包含三方面的内容,逻辑关系、存储关系及操作。
不同种类的数据结构适合于不同种类的应用,而部分甚至专门用于特定的作业任务。例如,计算机网络依赖于路由表运作,B 树高度适用于数据库的封装。

一、线性表

线性表是最基本、最简单、也是最常用的一种数据结构。线性表(linear
list)是数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列。

1、运行结果

在这里插入图片描述

2、具体代码
#include <stdio.h>
#include <stdlib.h>

#define maxsize 100 /*线性表的最大长度*/

typedef struct Linear_list{/*定义一个线性顺序存储表*/
int elem[maxsize];  /*线性表最大长度*/
int last; /*线性表中最后一个元素在数组elem[]中的位置*/
}SeqList;

/*表的初始化*/
SeqList *InitList( )
 { SeqList *L; //声明一个SepList类型的指针
   L=( SeqList *) malloc(sizeof(SeqList));//malloc表示在堆栈中分配一块内存,sizeof(SeqList)是这块内存的大小,malloc函数返回的是一个指向刚开辟的内存的指针
                                            //然后(SeqList*)进行一个类型转换,把返回的指针转换为SeqList*这种类型的,这样就可以把这个指针赋给L了
   L->last=-1; /*初始组内没有数据,指针last+1,last=-1*/
   return L;
   }

/*初始化操作*/
void createlist(SeqList *lp)
{
  int i, data; //定义中间变量i和元素变量data
  lp->last=0;
  printf("\n please input datas of the list\n");
  for(i=1; i < maxsize; i++)
  {
        scanf(" %d", &data); //&data是表示变量i的地址,&是取地符号
        if(data== -1) break; //-1输入结束
        lp->elem[i]=data;
        lp->last++; //每保存一个长度+1
  }
}

//遍历顺序表
void showlist(SeqList *lp)
{
  int i;//定义中间变量
  printf("\n These %d records are:\n", lp->last);
  if(lp->last<=0) //长度<=0就没有元素,直接返回
  {
       printf("No data!\n");
       return;
  }
  for(i=1; i<=lp->last; i++) // 遍历顺序表内部数组
      printf(" %d ", lp->elem[i]);
}

//插入元素到指定位置
int insertlist(SeqList *lp, int new_elem, int i)  //new_elem:新元素;i:插入位置
{  int j;
    if(lp->last==maxsize-1) //表空间已满,不能插入
   {
        printf("the list is full,can not insert.");
        return(0);
   }
   if(i<1 || i>lp->last+1) //检查插入位置的正确性
   {
        printf("\n%d is invalid value",i);
        return(0);
   }
   for(j=lp->last;j>=i-1;j--){   //结点移动
    lp->elem[j+1]=lp->elem[j];
   }
   lp->elem[i]=new_elem; //新元素插入
   lp->last++; // last仍指向最后元素

   return(1);//插入成功,返回
}

//删除某个位置的元素
int deletelist(SeqList *lp, int i) // lp:顺序表,i:删除元素的位置
{
   int j;
   if(i<1 || i>lp->last)  //删除的位置非法,即超出范围
   {
        printf("elem not exist");
        return(0);
   }
   //从删除元素之后的第一个元素开始依次将后面元素向前移动一个位置
   for(j=i;j<=lp->last;j++){
    lp->elem[j]=lp->elem[j+1];//向上移动
   }
   lp->last--;//表长度减一

   return(1);//删除成功
}


//带头结点的单链表长度
int LengthList(SeqList *lp){
    int i=1;
     while(i<=lp->last){//输出表的长度
        i++;
     }
      printf(" \n Length is: %d ", lp->last);
}

//按值查找
int LocatList(SeqList *lp,int t){
    int k=1;
     while(lp->elem[k]!=t){//如果没有该值,继续查找
        k++;
     }
     if(k<=lp->last)//如果有该值,继续查找
     printf("search is success and %d is %d position\n",t,k);//则提示
}

int main()//主函数
{
    SeqList *L;
    int i, data;
    L = InitList();
    createlist(L);
    showlist(L);
    LengthList(L);//表长
    printf("\n insert:Enter i and data :\n"); //请求输入插入操作位置
    scanf("%d %d", &i, &data);
    insertlist(L, data, i);
    printf("\n list after insert:\n"); //请求输入需要插入的新元素
    showlist(L);//调用顺序表插入函数
    LengthList(L);
    printf("\n delete:Enter i:\n");//请求输入删除操作位置
    scanf("%d", &i);
    deletelist(L, i);
    printf("\n list after delete:\n");//删除后所输出
    showlist(L);
    LengthList(L);
    printf("\n please input the position you want to search:\n");//输入你想查询的数字
    scanf("%d", &i);
    LocatList(L,i);
    LengthList(L);

    return 0;

}

二、顺序栈

顺序栈是栈的顺序实现。顺序栈是指利用顺序存储结构实现的栈。采用地址连续的存储空间(数组)依次存储栈中数据元素,由于入栈和出栈运算都是在栈顶进行,而栈底位置是固定不变的,可以将栈底位置设置在数组空间的起始处;栈顶位置是随入栈和出栈操作而变化的,故需用一个整型变量top来记录当前栈顶元素在数组中的位置。

1、运行结果

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、具体代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define Status int
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define SElemType int

typedef struct
{
    SElemType *base;
    SElemType *top;
    int stacksize;
}SqStack;
void Menu();//菜单
void Select(SqStack *L);//选择菜单
Status InitStack(SqStack *S);//创建顺序栈
Status DestroyStack(SqStack *S);//销毁顺序栈
Status StackEmpty(SqStack *S);//判断栈空
Status ClearStack(SqStack *S);//清空顺序栈
Status StackLength(SqStack *S);//测量栈的长度
Status GetTop(SqStack *S, SElemType *e); //获得栈顶元素
Status Push(SqStack *S, SElemType e);//入栈
Status Pop(SqStack *S, SElemType *e);//出栈

void main()
{
    SqStack S;
    while (1)
    {
    Menu();
    Select(&S);
    }
}
void Menu()
{
    system("color 02");
    system("cls");
    printf("\n");
    printf("\t   ※※※※※※※※※※※※※※※※※※※※※※※※※※※※\n");
    printf("\t   ※                                                    ※\n");
    printf("\t   ※****************顺**序**栈**的**操**作**************※\n");
    printf("\t   ※                                                    ※\n");
    printf("\t   ※     1: 创建顺序栈            2: 销毁顺序栈         ※\n");
    printf("\t   ※                                                    ※\n");
    printf("\t   ※     3: 判断栈空              4: 清空顺序栈         ※\n");
    printf("\t   ※                                                    ※\n");
    printf("\t   ※     5: 测量栈的长度          6: 获得栈顶元素       ※\n");
    printf("\t   ※                                                    ※\n");
    printf("\t   ※     7: 入栈                  8: 出栈               ※\n");
    printf("\t   ※                                                    ※\n");
    printf("\t   ※     9: 数制转换              10: 输出顺序栈        ※\n");
    printf("\t   ※                                                    ※\n");
    printf("\t   ※                     0: 退出                        ※\n");
    printf("\t   ※                                                    ※\n");
    printf("\t   ※※※※※※※※※※※  B U G ※※※※※※※※※※※※※\n");
    printf("\n\n\t\t   请选择操作:");
}
void Select(SqStack *S)
{
    int a, i;
    char c;
    SElemType e;
    while (1)    //输入检测
    {
    scanf("%d", &a);
    getchar();
    if (a >= 0 && a <= 10)
    break;
    else
    printf("\t\t   非法数据,请重新输入:");
    }
    switch (a)
    {
    case 1: InitStack(S);
    printf("\n按任意键继续...");
    getch();
    system("cls");
    break;
    case 2:DestroyStack(S);

    printf("\n按任意键继续...");
    getch();
    system("cls");
    break;
    case 3:
    if (StackEmpty(S) == FALSE)
    printf("顺序栈不为空!");
    else
    printf("顺序栈为空!");
    printf("\n按任意键继续...");
    getch();
    system("cls");
    break;
    case 4:
    ClearStack(S);
    printf("\n按任意键继续...");
    getch();
    system("cls");
    break;
    case 5:StackLength(S);
    printf("\n按任意键继续...");
    getch();
    system("cls");
    break;

    case 6:
    if (S->top - S->base > 0)
    {
    GetTop(S, &e);
    printf("栈顶的元素值为:%d", e);
    }
    else
    {
    printf("没有所查的位置!");
    }
    printf("\n按任意键继续...");
    getch();
    system("cls");
    break;
    case 7:
    printf("请输入入栈元素个数:\n");
    scanf("%d", &a);
    for (i = 0; i < a; i++)
    {

    printf("请输入数据元素:");
    scanf("%d", &e);
    Push(S, e);
    }

    printf("\n按任意键继续...");
    getch();
    system("cls");
    break;

    case 8:
    if (S->base == S->top)
    {
    printf("没有数据!\n");
    }
    else
    {
    Pop(S, &e);
    printf("出栈的元素为%d", e);
    }
    printf("\n按任意键继续...");
    getch();
    system("cls");
    break;

    case 9:
    conversion();
    printf("\n按任意键继续...");
    getch();
    system("cls");
    break;

    case 10:StackTraverse(S);
    printf("\n按任意键继续...");
    getch();
    system("cls");
    break;
    case 0:
    exit(0);    //退出系统
    }

}



    return OK;
}

Status DestroyStack(SqStack *S)    //销毁顺序栈
{
    if (S->top - S->base > 0)
    {
    free(S->base);
    S->base = NULL;
    S->top = NULL;
    }
    else
    printf("顺序表不存在!");
    return OK;
}

Status StackEmpty(SqStack *S)    //判断栈空
{
    if (S->top - S->base > 0)
    {
    return FALSE;
    }
    else
    {
    return TRUE;
    }
}

Status ClearStack(SqStack *S)    //清空顺序栈
{
    S->top = S->base;
    return OK;
}

Status StackLength(SqStack *S)    //测量栈的长度
{
    printf("顺序表长度为:%d", S->top - S->base);
    return OK;
}

Status GetTop(SqStack *S, SElemType *e)    //获得栈顶元素
{
    if (S->top == S->base)
    exit(ERROR);
    *e = *(S->top - 1);
    return OK;
}
Status Push(SqStack *S, SElemType e)    //入栈
{
    if (S->top - S->base >= S->stacksize)
    {
    S->base = (SElemType *)realloc(S->base, (S->stacksize + STACKINCREMENT) * sizeof (SElemType));
    if (!S->base) exit(OVERFLOW);
    S->top = S->base + S->stacksize;
    S->stacksize += STACKINCREMENT;
    }

    *S->top++ = e;
    return OK;
}
Status Pop(SqStack *S, SElemType *e)    //出栈
{
    if (S->top == S->base)
    return ERROR;
    *e = *--S->top;
    return OK;
}
void conversion()    //数制转换(十进制数转换成八进制数)
{
    SqStack S;
    int N,e;
    InitStack(&S);
    printf("请输入非负十进制整数:\n");
    scanf("%d", &N);
    while (N)
    {
    Push(&S, N % 8);
    N = N / 8;
    }
    printf("十进制数转换成八进制数为:\n");
    while (!StackEmpty(&S))
    {
    Pop(&S, &e);
    printf("%d", e);
    }

}
Status StackTraverse(SqStack *S)    //输出顺序栈
{
    int i;
    if (S->base == S->top)
    {
    printf("没有数据!");
    return ERROR;
    }
   
    }
    return OK;
}

三、链表

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。

1、运行结果

在这里插入图片描述

2、具体代码
#include "stdio.h"
#include "malloc.h"
typedef int ElemType;
typedef  struct LNode{
    ElemType data;    //数据域
    struct LNode *next;    //指针域
}LNode,*LinkStack;    //栈类型定义

//初始化链栈
void InitStack(LNode *lst){
    //申请头结点
    lst = (LNode *)malloc(sizeof(LNode));
    //指针域置空
    lst->next = NULL;
}

//判断链栈是否为空
int IsEmpty(LNode lst){
    //判断头结点的指针域是否为空
    if(lst.next == NULL){
    return 1;
    }
    else{
    return 0;
    }
}

//入栈
void push(LNode *lst,ElemType n){
    LNode *p;
    int i;

    //为新的结点申请空间
    p = (LNode *)malloc(sizeof(LNode));

    for(i = 0;i<n;i++){
    //为数据域赋值
    scanf("%d",&p->data);
    }

    //将新插入的结点指向原来的栈顶结点
    p->next = lst->next;

    //头结点指向新入栈的结点
    lst->next = p;
}

//出栈
int pop(LNode *lst,ElemType *x){
    //判断链栈是否为空
    if(lst->next == NULL){
    return 0;
    }

    LNode *p;
    //获取出栈结点
    p = lst->next;
    //获取出栈结点的数据域
    *x = p->data;

    //出去栈顶元素
    lst->next = p->next;
    //释放栈顶元素
    free(p);

    return 1;
}

//获取栈顶元素
int GetTop(LNode *lst) {
    //判断头结点的指针域是否为空
    if(lst->next!=NULL){
    return lst->next->data;
    }
}

int main(){
    LNode lst;
    int i;
    int x;
    int j;
    //初始化
    InitStack(&lst);

    printf("\n");

    printf("请输入入栈元素的个数:\n");
    scanf("%d",&i);
    printf("请输入入栈元素:\n");
    push(&lst,i);

    printf("目前栈顶元素为:");
    printf("%d",GetTop(&lst));
    printf("\n");

    printf("第一个出栈的元素为:");
    pop(&lst,&x);
    printf("%d",x);

}

四、顺序队列

顺序队列是队列的顺序存储结构,顺序队列实际上是运算受限的顺序表。和顺序表一样,顺序队列用一个向量空间来存放当前队列中的元素。由于队列的队头和队尾的位置是变化的,设置两个指针front和rear分别指示队头元素和队尾元素在向量空间中的位置,它们的初值在队列初始化时均应设置为0。

1、运行结果

在这里插入图片描述

2、具体代码
#define MAXQSIZE 100
typedef struct
 { int base[MAXQSIZE];
   int front;
   int rear;
 } Sqqueue;
Sqqueue enqueue(Sqqueue Q,int e)/*队列的入队函数*/
 { if ((Q.rear+1)%MAXQSIZE==Q.front)
       printf("ERROR\n");
   else
       {Q.base[Q.rear]=e;
    Q.rear = (Q.rear+1)%MAXQSIZE;    //队尾指针+1
       }
   return Q;
}
Sqqueue dequeue(Sqqueue Q,int *e)/*队列的出队函数*/
 {  int x;
    if (Q.front==Q.rear)
       printf("ERROR\n ");
    else
       { e=Q.base[Q.front];            //保存队头元素
    Q.front=(Q.front+1)%MAXQSIZE;//对头指针+1
       }
    return Q;
  }
void display(Sqqueue Q)/*队列元素输出函数*/
 { int k,m;
   k=Q.front;m=Q.rear;
   while(k!=m)
    { printf("%4d",Q.base[k]);
      k=(k+1)%MAXQSIZE;}
      printf("\n");
    }
main()/*主函数*/
 { Sqqueue Q;
   int i,n,x,y,e;
   Q.rear=Q.front=0; /*初始化顺序队列,使其成为空队列*/
   printf("\nplease input the length:");/*请求输入队列的长度*/
   scanf("%d",&n);
   printf("please input create data:\n  ");/*请求输入队列中各个元素*/
   for(i=1;i<=n;i++)
    {scanf("%d",&x);
     Q=enqueue(Q,x);}/*调用队列插入函数*/
   printf("the queue is:\n");
   display(Q);/*调用队列元素输出函数*/
   printf("please input a insert data:");/*请求输入需要插入的元素*/
   scanf("%d",&y);
   Q=enqueue(Q,y);/*调用队列插入函数*/
   printf("the queue after insert is:\n");/*提示显示执行入队操作后的队列*/
   display(Q);/*调用队列元素输出函数*/
   Q=dequeue(Q,&e);/*调用队列删除函数*/
   printf("the delete data queue after delete is:\n");/*提示显示执行出队操作后的队列*/
   display(Q);/*调用队列元素输出函数*/
 }

五、链式队列

链式队列(linked queue)是2018年公布的计算机科学技术名词,采用链式存储结构的队列。

1、运行结果

2、具体代码
# include<stdio.h>
# include<malloc.h>
# define TRUE 1
# define FALSE 0

/*链式队列*/
/*链式队列的存储结构*/
typedef struct Node {
    int data;    //数据域
    struct Node* next;    //指针域
}LinkQueueNode;

typedef struct {
    LinkQueueNode* front;
    LinkQueueNode* rear;
}LinkQueue;

/*链式队列的初始化*/
int InitQueue(LinkQueue* Q) {
    Q->front = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
    if (Q->front != NULL) {
    Q->rear = Q->front;
    Q->front->next = NULL;
    return TRUE;
    }
    else
    return FALSE;    //溢出
}

/*链式队列的创建*/
void CreateQueue(LinkQueue* Q) {
    LinkQueueNode* NewNode;
    int c, flag = 1;
    while (flag) {
    scanf("%d", &c);
    if (c != 0) {
    NewNode = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
    NewNode->data = c;
    Q->rear->next = NewNode;    //新结点插入到队尾
    Q->rear = NewNode;    //修改队尾指针
    }
    else {
    flag = 0;
    NewNode->next = NULL;
    }
    }
}

/*链式队列入队*/
int EnterQueue(LinkQueue* Q, int x) {
    /*将数据元素x插入到队列Q中*/
    LinkQueueNode* NewNode;
    NewNode = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
    if (NewNode != NULL) {
    NewNode->data = x;
    NewNode->next = NULL;
    Q->rear->next = NewNode;    //新结点插入到队尾
    Q->rear = NewNode;    //修改队尾指针
    return TRUE;
    }
    return FALSE;
}

/*链式队列出队*/
int DeleteQueue(LinkQueue* Q, int* x) {
    /*将队列Q的队头元素出队,并保存到x中*/
    LinkQueueNode* p;
    if (Q->front == Q->rear)    //空队列
    return FALSE;
    p = Q->front->next;    //p指向队头元素
    Q->front->next = p->next;    //队头元素p出队
    if (Q->rear == p)    //若队中只有一个元素p,则p出队后成为空队
    Q->rear = Q->front;
    *x = p->data;
    free(p);
    return TRUE;
}

/*链式队列输出*/
void Display(LinkQueue* Q) {
    if (Q->front == Q->rear)    //空队列
    printf("空队列!\n");
    else {
    LinkQueueNode* p;
    p = Q->front->next;    //p指向队头元素
    while (p != NULL) {
    printf("%d ", p->data);
    p = p->next;
    }
    printf("\n");
    }
}

int main() {
    int x;
    LinkQueue Q;
    InitQueue(&Q);    //初始化

    printf("创建队列(以0结束):");    //创建
    CreateQueue(&Q);
    printf("创建的队列元素为:");
    Display(&Q);

    EnterQueue(&Q, 5);    //入队
    printf("入队后队中元素为:");
    Display(&Q);

    DeleteQueue(&Q, &x);    //出队
    printf("出队元素为:%d\n", x);
    printf("出队后队中元素为:");
    Display(&Q);
    return 0;
}

六、字符串

字符串主要用于编程,概念说明、函数解释、用法详述见正文,这里补充一点:字符串在存储上类似字符数组,所以它每一位的单个元素都是可以提取的,如s=“abcdefghij”,则s[1]=“b”,s[9]=“j”,这可以给我们提供很多方便,如高精度运算时每一位都可以转化为数字存入数组。

1、运行结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、具体代码
#include<stdio.h>
#include<windows.h>
#include<stdlib.h>
voiddelstr();//删除顺序串
voidsearchstr();//查找顺序串
voidstrlong();//求串长
charstr[100];
charstrlength=0;
intmain()
{
system("colorf0");//背景白色
while(1)
{
showmenu();
processmenu();
system("pause");
system("cls");
}
}
voidshowmenu()
{
puts("~~~~~~~~~~~~~~~~~~~~~~~");
puts("\t\t串基本操作的编程实现");
puts("~~~~~~~~~~~~~~~~~~~~~~~");
puts("|~~~\t\t1、建立顺序串\t\t~~~|");
puts("|~~~\t\t2、显示\t\t\t~~~|");
puts("|~~~\t\t3、修改\t\t\t~~~|");
puts("|~~~\t\t4、插入\t\t\t~~~|");
puts("|~~~\t\t5、删除\t\t\t~~~|");
puts("|~~~\t\t6、查找\t\t\t~~~|");
puts("|~~~\t\t7、求串长度\t\t~~~|");
puts("|~~~\t\t0、退出程序\t\t~~~|");
puts("~~~~~~~~~~~~~~~~~~~~~~~");
puts("");
printf("请输入您的选择:");
}
voidprocessmenu()
{
intmenuchoice;//菜单选择
scanf("%d",&menuchoice);
switch(menuchoice)
{
case1:
setstr();
fflush(stdin);
break;
case2:
showstr();
fflush(stdin);
break;
case3:
modstr();
fflush(stdin);
break;
case4:
insertstr();
break;
case5:
delstr();
fflush(stdin);
break;
case6:
searchstr();
fflush(stdin);
break;
case7:
strlong();
fflush(stdin);
break;
case0:
puts("\n~~~~~~~~~~~~~~~~~~~~~~~~");
puts("\t\t欢迎下次再用!");
puts("~~~~~~~~~~~~~~~~~~~~~~~~\n");
exit(0);
default:
printf("输入错误!请重新输入...\n");
}
}
voidsetstr()
{
str[100]=NULL;
strlength=0;
fflush(stdin);
printf("请输入要创建的字符串(100以内,回车结束):");
gets(str);
puts("创建成功!");
for(inti=0;str[i]!='\0';i++)//统计字符串个数
{
strlength++;
}
}
voidshowstr()
{
if(strlength==0)
printf("顺序串为空!\n");
else
{
intj=0;
printf("位置:");
for(inti=strlength/10;i!=-1;i--)
{
printf("|---%d----|",j);
j++;
}
printf("\n位置:");
for(inti=strlength/10;i!=-1;i--)
{
printf("1234567890");
}
printf("\n当前:");
for(j=0;str[j]!='\0';j++)
printf("%c",str[j]);
printf("\n");
}
}
voidmodstr()
{
if(strlength==0)
printf("顺序串为空!\n");
else
{
intfirst,last;
intlength=0;
inti,j;
charmodstr[100];
showstr();
printf("请输入要修改的初始位置:");
scanf("%d",&first);
printf("请输入要修改的终止位置:");
scanf("%d",&last);
printf("请输入新的字符串:");
fflush(stdin);
gets(modstr);

for(j=last;j!=strlength+1;j++)//数据前移
{
str[j-(last-first+1)+length]=str[j];
}
strlength-=(last-first+1)-length;
}
elseif(length==last-first+1)//新字符串长度等于修改字符串
{
for(inti=0;first!=last+1;first++,i++)
{
str[first-1]=modstr[i];
}
printf("修改成功!\n");
}
elseif(length>last-first+1)//新字符串长度大于修改字符串
{
for(i=strlength;i>last-1;i--)//原数组后移
{
str[i+length-(last-first+1)]=str[i];
}
for(i=first-1,j=0;modstr[j]!='\0';i++,j++)//插入覆盖
{
str[i]=modstr[j];
}
printf("修改成功!\n");
strlength+=length-(last-first+1);
}
showstr();
}
}
voidinsertstr()
{
if(strlength==0)
printf("顺序串为空!\n");
else
{
intlast;
inti,j,length;
charinsertstr[100];
showstr();
printf("请输入要插入的位置:");
scanf("%d",&last);
printf("请输入要插入的字符串:");
fflush(stdin);
gets(insertstr);
for(i=0;insertstr[i]!='\0';i++)//统计插入字符个数
length++;
for(i=strlength-1;i!=last-2;i--)//原数组后移
{
str[i+length]=str[i];
}
for(i=last-1,j=0;insertstr[j]!='\0';i++,j++)//插入覆盖
{
str[i]=insertstr[j];
}
printf("插入成功!\n");
strlength+=length;
showstr();
}
}
voiddelstr()
{
if(strlength==0)
printf("顺序串为空!\n");
else
{
showstr();
inti,j;
intfirst,last;
printf("请输入要删除的初始位置:");
scanf("%d",&first);
printf("请输入要删除的终止位置:");
scanf("%d",&last);
for(i=first-1,j=last;i!=last;i++,j++)//前移覆盖
{
str[i]=str[j];
}
strlength-=last-first+1;
showstr();
}
}
voidsearchstr()
{
if(strlength==0)
printf("顺序串为空!\n");
else
{

for(i=0;searchstr[i]!='\0';i++)//统计插入字符个数
length++;
while(str[position]!='\0')//判断主串是否结束
{
for(i=position,j=0;searchstr[j]==str[i];i++,j++)//比较
{
if(searchstr[j+1]=='\0')//判断查找串是否结束
{
flag=1;
break;
}
}
position++;//下一个字符
if(flag==1)
break;
}
if(flag==1)
{
printf("查找成功!\n");
showstr();
printf("查找:");
position--;
while(position--)
printf("");
for(i=0;searchstr[i]!='\0';i++)
printf("%c",searchstr[i]);
printf("\n");
//printf("该字符串的初始位置为:%d\n",position);
//printf("该字符串的末尾位置为:%d\n",length+position-1);
}
else
printf("查找失败!\n");
}
}

{
printf("目前字符串的长度为:%d\n",strlength);
}

七、二叉树

二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。二叉树特点是每个节点最多只能有两棵子树,且有左右之分。

1、运行结果

在这里插入图片描述

2、具体代码
#include <stdio.h>
typedef struct Bitnode
  {char data;
   struct Bitnode *lchild,*rchild;
  }Bitnode,*Bitree;
Bitree creat(Bitree T)/*建立二叉树函数*/
 { char x;
   scanf("%c",&x);
   if (x=='#') T=NULL;
   else
     {T=(Bitree)malloc(sizeof(Bitnode));
      if (!T)
        {printf("OVERFLOW\n");
         exit(-1);
         }
      else
        {T->data=x;
         T->lchild=creat(T->lchild);
         T->rchild=creat(T->rchild);
        }
      }
   return T;
  }
Bitree preorder(Bitree T)/*先序遍历二叉树函数*/
 { if (T!=NULL)
    { printf("%c",T->data);
      preorder(T->lchild);
      preorder(T->rchild);
     }
  }
void midorder(Bitree T) /*中序遍历二叉树函数*/
 { if (T!=NULL)
    { midorder(T->lchild);
      printf("%c",T->data);
      midorder(T->rchild);
    }
 }
void backorder(Bitree T) /*后序遍历二叉树函数*/
 { if (T!=NULL)
    { backorder(T->lchild);
      backorder(T->rchild);
      printf("%c",T->data);
    }
  }
main()/*主函数*/
  { Bitree T=NULL; char x;
    printf("creat tree!\n");/*请求输入二叉树中各个元素*/
    T=creat(T);/*调用建立二叉树函数*/
    while(1)
     { printf("  1-preorder\n");
       printf("  2-midorder\n");
       printf("  3-backorder\n");
       printf("  4-exit\n");
       printf("please input the choose!(1-4):");/*请求选择遍历方式*/
       scanf("%d",&x);
       switch(x)
    {case 1: printf("the preorder is:");
                 preorder(T); /*调用先序遍历二叉树函数*/
                 break;
     case 2: printf("the midorder is:");
                 midorder(T); /*调用中序遍历二叉树函数*/
                 break;
     case 3: printf("the backorder is:");
                 backorder(T); /*调用后序遍历二叉树函数*/
                 break;
         case 4: return;
         default:printf("ERROR!\n");
         }
       printf("\n");
      }
  }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

木头科技

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

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

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

打赏作者

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

抵扣说明:

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

余额充值