20 计专

数据结构

第一题

1、领接表结构判断u与v之间有无路径

思路: 深度优先遍历或者广度优先遍历

typedef struct ArcNode{		//领接边 
	int adjvex;
	struct ArcNode *next;
}ArcNode; 

typedef struct VNode{		//顶点 
	int data; 
	ArcNode  *firstarc;
}VNode; 

typedef struct{				//领接表 
	VNode adjlist[maxsize];
	int vexnum, edgenum;
}AGraph;

//采用广度优先遍历
bool isroad(AGraph *G, int u, int v){
	int visited[G->vexnum];
	ArcNode *p;							 	//工作指针 
	int queue[maxsize];						//队列 
	int i,k,front=-1,rear=-1;
	
	for(i=0; i < G->vexnum; i++){			//初始化visited数组 
		visited[i] = 0;
	}
	queue[++rear] = u;
	visited[u] = 1;							//节点入队列
	while(rear != front){					//层次遍历 
		 k = queue[++front];				//出队
		 p = G->adjlist[k].firstarc;
		 while(p!=NULL){					//层次遍历该节点的领接点 
		 	if(visited[p->adjvex]==0){		//未被访问,入队,访问
			 	if(p->adjvex == v){			//如果存在回路,直接返回true 
			 		return true;
				 } 
		 		visited[p->adjvex] = 1;
		 		queue[++rear] = p->adjvex;
			 }
			 p = p->next; 
		 }
	} 
	return false;
}

第二题

2、链表的合并,将两个链表合并为一个升序链表(尾插法)(降序:头插法)

思路: 申请一个带头结点的链表进行插入,考虑两个节点数值相等的情况下需要两个指针一起移动

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

list merge(list head1, list head2){//默认不带头结点 
	struct node *newhead = (struct node *)malloc(sizeof(struct node));
	struct node *p1 = head1, *p2 = head2,*p = newhead; 
	while(p1 != NULL && p2 != NULL){//合并两个链表 
		if(p1->data > p2->data){	//p1大于p2 
			p->next = p2;
			p = p->next;
			p2 = p2->next;
		}
		else if(p1->data < p2->data){//p2大于p1 
			p->next = p1;
			p = p->next;
			p1 = p1->next;
		}
		else{						//p1等于p2 
			p->next = p1;
			p = p->next;
			p1 = p1->next;
			p2 = p2->next;
		}
	}
	if(p1!=NULL){				//处理剩余节点 
		p->next = p1;
	}
	else{
		p->next = p2;
	} 
	p = newhead->next;
	while(p!=NULL){
		printf("%5d",p->data);
		p = p->next;
	}
	return newhead->next;		//返回不带头结点的单链表 
} 

程序设计

第一题

1、计算数组的最大的滑动窗口数,最大连续子集的元素个数

思路:
动态规划,如果前面的值不为负数,那么加上当前的数肯定是要大
if dp[i-1]>0 dp[i] = dp[i-1] + a[i]
else dp[i]=a[i]
然后考虑是否比当前的最大值要大,更大的话,进行更新

int maxnum(int a[], int n){
	int tail, head,i,max=0;
	int dp[n];			//为当前以a[i]为结尾的最大连续元素和的最大值 
	dp[0] = a[0];
	for(i=1; i < n; i++){
		if(dp[i-1] < 0){		//如果前一个最大值为负数,直接舍弃 
			dp[i] = a[i];
			head = i;
		} 
		else{					//如果是正数就一直加 
			dp[i] = dp[i-1] + a[i];
		}
		if(dp[i] > max){		//超过了当前最大值,进行更新 
			tail = i;
			max = dp[i];
		}
	}
	printf("最大滑动窗口数为%d, 起始下标%d, 终止下标%d",tail-head+1, head, tail);
	return tail-head+1; 
}

第二题

2、删除链表里面的重复节点,带头结点
思路: 双重for循环比较,需要两个指针一个是工作节点,一个是当前节点的前驱节点(这里采用带头结点的链表)

list deletesame(list head){
	struct node *p=head->next, *pre=head, *q;
	while(p!=NULL){
		q = p->next;
		while(q!=NULL){
			if(p->data == q->data){//元素相同,则进行删除p节点 
				pre->next = p->next;
				free(p);
				p = pre->next; 
			}
			q = q->next; 
		}
		pre = p;			//继续往下找 
		p = p->next;
	}
	
	p = head->next;
	while(p!=NULL){
		printf("%-5d",p->data);
		p = p->next;
	}
} 

第三题

3、递归判断一个二叉树是否对称
思路:
递归实现:

  1. 左右节点均为空,返回true
  2. 左右节点有一个为空,返回false
  3. 左右节点不为空且左右节点不相等 返回 false
  4. 左右节点不为空且左右节点相等 递归判断左右子树
typedef struct tnode{
	int data;
	struct tnode *left, *right;
}*tree;

bool symmetry(tree p, tree q){
	if(p==NULL && q==NULL) return true;		//左右子树都空,对称
	else if(p==NULL|| q==NULL) return false;  //左右子树有一个不为空,不对称
	else if(p->data != q->data) 	return false; //左右节点不相等,不对称
	else									//左右子树节点不为空且相等,递归判断 
		return symmetry(p->left,q->right)&&symmetry(p->right,q->left);
} 

bool judge(tree root){
	if(root==NULL) return true;
	return symmetry(root->left, root->right); 
} 
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值