873数据结构算法题代码

目录

2011

奇偶交换排序的思路如下:第一趟对所有奇数的i,将a[i]和a[i+1]进行比较,第二趟对所有偶数的i,将a[i]和a[i+1]进行比较,每次比较时若a[i]>a[i+1],将二者交换;以后重复上述第二趟过程,直至整个数组有序。编写算法

void OeSort(int a[],int n){
    int flag,i,t;
    do{
        flag=0;
        for(i=0;i<n-1;i=+2){
            if(a[i>a[i+1]])
                flag=1;
            	t=a[i+1];
            	a[i+1]=a[i];
            	a[i]=t;
        }
        for(i=1;i<n-1;i=+2){
            if(a[i>a[i+1]])
                flag=1;
            	t=a[i+1];
            	a[i+1]=a[i];
            	a[i]=t;
        }
    }while(flag) 
        
}

设有一带头结点的单链表,编写算法将链表颠倒过来,要不用另外的数组或结点完成

void Reverse(LinkList &L){
    LNode *p,*q,t;
    p=L->next;
    q=p->next;
    p->next=NULL;
    while(q){
        t=q;
        q=q->next;
        t->next=p;
        p=t;
    }
    L->next=p;
}

2012

已知L是无表头结点的单链表,且p结点既不是首元结点,也不是尾元结点,设计算法以实现在p结点前插入s结点的功能

void Insert(LinkList &L,LNode *p){
    LNode *q,*s;
    q=L;
    if(q==p){
       	s=(LNode*)malloc(sizeof(LNode));
        s->next=p;
    }
    while(q->next!=p&&q){
        q=q->next;
    }
    if(q)
        s=(LNode*)malloc(sizeof(LNode));
    	s->next=p;
    	q->next=s;
}

设计算法统计一个二叉树中所有叶结点的数目及非叶结点的数目

int Sum(BiTree T){
    if(T==NULL){
        return 0;
    }
    else if(||T->lchlid==NULL&&T->rchild==NULL)
        return 0;
    
   	else
        return Sum(T->lchild)+Sum(T->rchild)+1;
}

2013

假设循环单链表不空,且无表头结点亦无表头指针,指针p指向链表中某结点。请设计一个算法,将p所指结点的前驱结点变为p所指的后继结点

void Exchange(LNode *p){
    LNode *pp,*ppp;	//pp为p的前驱,ppp为p的前驱
    ppp=p,pp=p->next;
    while(pp->next!=p){	//找到pp和ppp
        pp=pp->next;
        ppp=ppp->next;
    }
    pp->next=p->next;
   	ppp->next=p;
    p->next=pp;
}

用非递归方式写出二叉树中序遍历算法

void InOrder(BiTree T){
    BTNode *p;
    Stack S;
    InitStack(S);
    p=T->next;
    while(p||!IsEmpty(S)){
        if(p){
            Push(S,p);
            p=p->lchild;
        }
        else
            Pop(S,p);
        	visit(p);
        	p=p->rchild;
    }
}

🐷2014B

设L为单链表的头节点地址,其结点的数据都是正整数且无相同的,试设计利用直接插入法的原则把该链表整理成数据递增的有序单链表的算法

void Sort(LinkList &L){
    LNode *pre,*p,*q,*t;
    p=L;
    pre=L->next;
    q=p->next;
    while(q){
        if(q->data<pre->data)
            t=q;
        	q=q->next;
        	while(p->next!=t&&t->data>p->next->data){//找到t所插位置的前驱
                p=p->next;
            }
        	t->next=p->next;
        	t->next=p;
        	p=L;
    }
}

设二叉树采用二叉链表作为存储结构。写出算法实现前序遍历顺序输出二叉树中结点的非递归算法

void PreOrder(BiTree L){
    BLNode *p;
    Stack S;
    p=L->next,InitStack(S);
    while(p||!StackEmpty(S)){
        if(p)
            visit(p);
            Push(S,p);
        	p=p->lchild;
        else
            Pop(S,p);
        	p=p->rchild;
    }
    
}

🧐2015B

折半查找递归算法

int Binary(ElemType ST[],ElemType key,int low,int high){
	int mid;
	mid=(low+high)/2;
	if(low>high)
		return -1;
	if(ST[mid]==key)
		return mid;
	else if(low<=high&&ST[mid]>key)
		return Binary(ST,key,low,mid-1);
	else
		return Binary(ST,key,mid+1,high);
	return -1;
}

设有两个集合A和集合B,要求设计生成集合A交B的算法,其中集合A,B和C用链式存储结构表示

void Intersection(LinkList A,LinkList B,LinkList &C){
    LNode *pa,*pb,*pc;
    pa=A->next,pb=B->next;pc=C;
    while(pa){
        while(pb){
            if(pa->data==pc->data)
                pc->next=pa;
            	pc=pa;
            pb=pb->next;
        }
        pb=B->next;
        pa=pa->next;
    }
    pc->next=NULL;
}

🚡2016B

查找二叉树指定结点的层数

int Level(BLinList T,BLNode *p){
    if(T==NULL)
        return 0;
    if(T->data==p->data)
        return 1;
    int left=Level(L->lchild,p);//从左子树开始找
    int right=Leve(L->rchild,p);//从右子树开始找
    if(left==0&&right==0)		//两个子树都没有找到
        return 0;
    else
        return left+right+1;
}

🦼2017B

有相同的

🧃2018A

编写一算法实现:输入任意一个非负十进制数,显示输出与其等值的八进制数

void PrintOctal(int num){
    Stack s;
    int re;
    InitStack(s);
    while(num!=0){
        re=num%8;
        Push(s,re);
        num=num/8;
    }
    if(IsEmpty(s))
        printf("0/n");
    while(!IsEmpty(s)){
        Pop(s,re);
        printf("%d",re);
    }
}

若由键盘输入若干个整数,请写出按输入数据逆序建立一个带头节点的单链表的算法

void Bulit(LinkList &L){
    LNode *s;
    int d;
    L->next=NULL;
    do{
        printf("请输入任意一个数:/n");
        scanf("%d",&d);
        s=(LNode*)malloc(sizeof(LNode));
        s->data=d;
        s->next=L->next;
        L->next=s;
    }while(getchar()!='Q')
}

已知单链表L中的结点是按值非递减有序排列的,试写一个算法将值为x的结点插入表L中,使得L仍然有序

void Insert(LinkList &L,ElemType x){
    LNode *p,*s;
    p=L;
    while(p->next!=NULL){
        if(x<=p->next->data)
            s=(LNode*)malloc(sizeof(LNode));
        	s->data=x;
        	s->next=p->next;
        	p->next=s;
        p=p->next;
    }
}

编写向类型为List的线性表L中第i个元素位置插入一个元素的算法,假定不需要对i的值进行有效性检查,同时不需要检查存储空间是否用完

void PosInsert(LinkList &L,ElemType x,int i){
    LNode *p,*s;
    int j;
    j=0;
    p=L->next;
    while(p&&j<i-1){
        p=p->next;
        j++;
    }
    if(p){
        s=(LNode*)malloc(sizeof(LNode));
        s->data=x;
        s->next=p->next;
        p->next=s;
    }
}

🏍2018B

已知一个顺序存储的线性表的元素非递减有序排列,设计一个算法删除表中值相同的元素算法

void Delete(SeqList &L){
    int i,j;
    for(i=1;i<L.length;++i){
        if(L.data[i-1]==L.data[i])
            for(j=i;j<L.length;++j){
                L.data[j-1]=L.data[j];
            }
        	L.length--;
        	--i;
    }
}

有一个线性表,其头指针为head,编写一个函数计算数据域为x的节点个数

int Count(LNode *head,ElemType x){
    LNode *p;
    int count=0;
    p=head->next;
    while(p){
        if(p->data=x)
            count++;
    }
    return count;
}

编写一个算法求链表长

void Length(LinkList L){
    LNode *p;
    int len=0;
    p=L->next;
    while(p){
        len++;
        p=p->next;
    }
    return len;
}

借助栈编写一个算法,将一个带头结点的单链表倒置

void Reverse(LinkList &L){
    LNode *p,*q;
    Stack s;
    InitStack(s);
    p=L;
    q=L->next;
    while(q){
        Push(s,q);
        q=q->next;
    }
    while(!IsEmpty(s)){
        Pop(s,q);
        p->next=q;
        p=q;
    }
    p->next=NULL;	
}

不借助栈

思路:把相邻的两个结点逆序,开始时用p和q分别指向第一个和第二个结点,对其进行逆序先用t来保存q结点,q再指向下个结点,然后用t指向q,其次把t赋值给p,直到q为空

void Reverse(LinkList &L){
    LNode *p,*q,*t;
    p=L->next;
    q=p->next;
    p->next=NULL;
    while(q){
        t=q;
        q=q->next;
        t->next=p;
        p=t;
    }
	L->next=p;
}

🐱‍💻2019A

在一个带头节点的单链表中所有元素节点的数据值按非递减排列,删除表中所有大于min且小于max的元素

void Delete(LinkList &L,int min,int max){
    if(L==NULL){
        return;
    }
    LNode *p,*r,*t;
    p=L;
    r=p->next;
    while(r->next){
        if(p->next->data>mim&&p->next->data<max)
            t=r;
            r=r->next;
            p->next=t;
        	free(t);
        else
            r=r->next;
            p=p->next;
    }
}

构造一个单链表将字符串s中的每一个字符依次存放到该单链表中去,单链表中每个节点存放4个字符

//思路:在s中从下标为j=0开始依次把4个字符赋值给新建节点t->data[i];其中0=<i<4,然后把t节点连接到用p指向链表的末尾节点,直到j不小于s.length,循环停止。
#define size 4
typedef struct Node{
    char data[size];
    struct Node *next
}Node,*LinkList;

Node  *Insert(SSTring s){
   LinkList head;
    Node *p,*t;
    int i,j;
    p= head=(Node*)malloc(sizeof(Node));//建立头节点初始时并且用p指针指向其
    j=0;
    //当j不小于s的长度时循环结束
    while(j<s.length){
        t=(Node*)malloc(sizeof(Node));//创立新节点
        //依次把j到j+3共四个值复制给t->data[i];
        for(i=0;i<size;++i){
            t->data[i]=s.[j];
            j++;
        }
        //把s连接到p的后面
        p->next=s;
        s->next=NULL;
        //用p指向s;
        p=s;
    }
    return head;
}

🐱‍🚀2019B

设计一个算法,从顺序表中删除最小值的元素(设循序表中元素均不同)。空出的位置由最后一个元素填补,若顺序表为空则显示出错信息并退出运行

void Delete(SqList &L){
    if(L)
        printf("表空/n");
        return;
    int mid,i;
    mid=0;
    for(i=0;i<L.length;++i){
        if(L.data[i]<L.data)
            min=i;
    }
    if(min!=L.length-1)
        L.data[min]=L.data[L.length-1];
    L.length--;
}

设计一个算法,在非递减有序的带头节点的单链表中删除值相同的多余节点

void DeleteSM(LinkList &L){
    LNode *p,*r,*t;
    p=L->next;
    r=p->next;
    while(r){
        if(p->data==r->data)
            t=r;
        	r=r->next;
        	p->next=r;
       		free(t);
        else
            p=p->next;
        	r=r->next;
    }
}

改进

p指针扫描链表,如果p所指结点值和其后继节点值相等则data3和data5连接,否则p继续扫描链表直至表尾

graph LR A[data1] -->B[data2] B --> C[data3] C --> D[data4] D --> E[data5] p --> C

代码

void DeleteNode(LinkList &L){
    LNode *p;
    p=L;
    while(p->next!=NULL){
        if(p->data==p->next->data)
            p->next=p->next->next;
        p=p->next;
    }
}

仅用队列的ADT函数和少量变量设计以下算法

已知一个队列Q,其节点的数据域为一个自然数。输入一个自然数n,与队头节点数据配对。如果相等,则删除队头节点;如果不相等或队列为空,则把n插入队列。如果输入数为0,则结束 处理。

队列ADT函数有;

void enQueue (Queue q,ElemType e);元素e入队

ElemType deQueue(Queue q ,ElemType);出队,将对头元素放入e

int IsEmpty(Queue q);判断对空,返回值是1表示队空,返回值0表示非空

void GetHead(Queue q ElemType x)

void Insert(Queue &Q){
    int e,n;
    printf("输入一个自然数,输入0则结束/n");
    scanf("%d",&n);
    GetHead(Q,e);
    //如果输入数为0,则结束处理
    if(n==0)
        return;
    //n与e不相等或队列为空,则把n插入队列
    if(e!=n||isEmpty)
       enQueue(Q,n);
    //n与e
    if(e==n)
        deQueue(Q,e);
}

设非空二叉树采用二叉链表储存结构,根节点的指针为bt。利用二叉树的中序遍历,编写判断该二叉树是否为二叉排序数的非递归算法

typedef struct BNode{
    ElemType data;//存储的数据
    struct BNode *lchild,rchild;//左右孩子指针
} *BLinkList,BNode;

bool isBST(BLinkList &bt){
    BNode *p;
    int min=INT_MIN;
    Stack s;
    InitSack(s);
    p=bt;
    while(p||!isEmpty(s)){
        if(p)
            Push(s,p);
            p=p->lchild;
        else
            Pop(s,p);
        	if(p->data>min)
                break;
        	min=p->data;
        	p=p->rchild;
    }
    if(p&&isEmpty(s))
        return true;
    return false;
}	

🐱‍👓2020A

设计算法,删除带头节点的单链中值最小的节点(节点的数根据值均不同)

void Delete(LinkList &L){
    LNOde *p *t;
    ElemType min;
    p=L->next;
    t=p;
    min=p->data;
    while(p){
        p=p->next;
        if(p->data<min&&p)//如果p节点中的值小于min且p不为空,则把p的值赋给min,并用t指向此时的p
            min=p->data;
       		t=p;
    }
    free(t);
}

设计算法将两个非递减的带头节点的单链表合并为非递增的带头节点的有序链表。要求结果链表仍使用原来两个链表的存储空间,不另占用其他存储空间。同时结果链表允许有重复的数据。

void Emerg(LinKLisk &La,LinkList &Lb){
    LNode *pa,*pb,*Lc,*pre;
    pa=La->next;
    pb=Lb->next;
    Lc=La;
    Lc->next=NULL;
    while(pa&&pb){
        if(pa->data<=pb->data)
            pre=pa->next;
        	pa->next=Lc->next;
        	Lc->next=pa;
       		pa=pre;
        else
            pre=pb->next;
        	pb->next=Lc->next;
        	Lc->next=pb;
        	pb=pre;
    }
    while(pa){
       pre=pa->next;
       pa->next=Lc->next;
       Lc->next=pa;
       pa=pre;
    }
    while(pb){
        pre=pb->next;
        pb->next=Lc->next;
        Lc->next=pb;
        pb=pre;
    }
    La=Lc;
    free(Lb);
}

🛺2021B

线性表中的元素按递增有序排列,针对顺序表的存储方式,设计一个算法完成删除线性表中值介于a与b(a<=b)之间的元素

  1. 算法思想:当a<L.data[i]<b时把i后面的元素往前移,每次前移L.length都减1。

  2. 算法如下:.

    void Delete(SeQList &L,ElemType a,ElemType b){
        int i,j;
        for(i=1;i<L.length;++i){
            if(L.data[i]>a&&L.data[i]<b)
                for(j=i+1;j<L.length;++j){
                    L.data[j-1]=L.data[j];
                }
            L.length--;
        }
    }
    

A=(a1,a2,……an),B=(b1,b2,…..bm)是两个递增有序的线性表(其中n,m均>1),且所有元素均不同。假设A,B均采用带头节点的单链表存放,设计一个尽可能高效的算法判断B是否为A的一个连续子序列,并分析你设计的算法的时间复杂度和空间复杂度

时间复杂度:O(m+n)

空间复杂度:O(1)

bool SubSeq(LinkList A,LinkList B){
    LNode *pa,*pb;
    pa=A->nxet;
    pb=B-next;
    while(pa&&pb){
        if(pa-data<pb->data)
            pa=pa->next;
  		else if(pa->data<pb->data)
            pb=pb->next;
        else
            break;
    }
    while(pa&&pb&&pa->data=pb->data){
        pa=pa->next;
        pb=pb->next;
    }
    if(pb==NULL)
        return true;
    else
        return false;
        
    
}

💌假设二叉树T每个节点值为单个字符,采用二叉链储存结构,设计一个算法,ElemType MaxNode(BTNode *T) 求该二叉树T中的最大节点值,空树返回 ’0‘

ElemType MaxNode(BTNode *T){
    BTNode *p;
    p=T;
    ElemType x='0';
    Stack s;
    InitStack(s);
    while(!isEmpty(s)||p){
        if(p)
            Push(s,p);
        	p=p->lchild;
        else
            Pop(s,p);
        	if(p->data<x)
                x=p->data;
        	p=p->rchild;
    }
    return x;
    
}

💟2022B

试写出递归的二分查找(折半查找)算法。

int Binary(ElemType A[],ElemType key,int low,int high){
    int mid=(low+high)/2;
    if(low>high)
        return -1;
    if(key=A[mid])
        return mid;
     else if(key>A[mid])
        return Binary(A,key,mid+1,high);
     else
        return Binary(A,key,low,mid-1);
         
     return -1;
}

假设以I和O分别表示入栈和出栈操作,栈的初态和终态均为空,进栈和出栈的的操作序列可表示为仅由I和O组成的序列。

  1. 下面所示的序列中哪些是合法的(AD)

    A. IOIIOIOO B. IOOIOIIO C. IIIOIOIO D. IIIOOIOO

  2. 通过对1的分析,写出一个算法判定所给的操作序列是否合法。若合法返回true;否则返回false(假定被判判定的操作序列已经存入一维数组)

//依次扫描数组,如果是I操作字符则把I入栈,如果是O操作字符则判断栈是是否为空,如果栈空则表示此时O操作多余I操作,序列必不合法,返回false,栈不为空则把栈顶元素出栈。当扫描完后,如果栈空则说明I与O一一对应,返回true,栈不空则说明I操作多余O操作,序列不合法,返回false。
bool IsLegal(char A[],int n){
    int i;
    Stack(s);
    InitStack(s);
    for(i=0;i<n;++i){
        char c=A[i];
        if(c=='I')
            Push(s,c);
        else if(c=='O')
            if(IsEmpty(s))
                return false;
        	else
                Pop(s,c);
            
    }
    if(IsEmpty(S))
        return true;
    return false;
}

有两个递增有序表,所有元素为整数,均采用带头节点的单链有序表存储,节点类型定义如下:

typedef struct node
{	
	int  data;
	struct node *next;
}LinkNode;

设计一个尽可能高效的算法,将两个递增有序单链表ha,hb合并为一个递减有序单链表,hc要求算法空间复杂度为0(1)

LinkNode *Merge(LinkNode *ha,LinkNode *hb){
    LinkNode *hc=ha;
    node *pa,*pb,pre;
    pa=pa->next;
    pb=pb->next;
    hc-next=NULL;
    while(pa&&pb){
        if(pa->data<pb->data)
        	pc=pa->next;
        	pa->next=hc->next;
        	hc->next=pa;
        	pre=pre;
        else if(pa->data>pb->data)
        	pre=pb->next;
        	pb->next=hc->next;
        	hc->next=pb;
        	pb=pre;
        else
            pre=pa->next
            pa->next=hc->next;
        	hc->next=pa;
        	pa=pre;
        	pb=pa->next;
    }
    while(pa){
        pc=pa->next;
        pa->next=hc->next;
        hc->next=pa;
        pre=pre;
    }
     while(pb){
        pre=pb->next;
        pb->next=hc->next;
        hc->next=pb;
        pb=pre;
    }
    free(Lb);
    return Lc; 
}
posted @ 2023-11-30 17:07  lkylin070  阅读(202)  评论(0)    收藏  举报