【数据结构】算法设计(1)

记录线性表和二叉树常见的算法设计

定义结点
#define maxsize 20

// 定义链表结点
typedef struct lnode {
	int data;
	struct lnode* next;
} LNode;


//定义二叉树结点
typedef struct bnode {
	int data;
	struct bnode* lchild;
	struct bnode *rchild;
} BNode;
建立链表和二叉树
//向BST内插入节点
void Insert(BNode *&bt, int x) {
	if (!bt) {
		bt = new BNode();
		bt->data = x;
		bt->lchild = bt->rchild = 0;
	}
	else if (bt->data > x) {
		Insert(bt->lchild, x);
	}
	else {
		Insert(bt->rchild, x);
	}
}

// 建立BST
void CreateBtree(BNode *&bt, int nums[], int n) {
	int i;
	for (i = 0; i < n; i++) {
		Insert(bt, nums[i]);
	}
}

//建立链表,采用尾插法,头结点不存储数据
void CreateList(LNode*& l, int nums[], int n) {
	int i;
	LNode* p = l;
	for (i = 0; i < n; i++) {
		LNode* s = (LNode*)malloc(sizeof(LNode));
		s->data = nums[i];
		p->next = s;
		s->next = NULL;
		p = s;
	}
}
判断两颗二叉树是否相同
bool Same(BNode* a, BNode* b) {
	if (!a && !b) {
		return 1;
	}
	else if (!a || !b || a->data != b->data) {
		return 0;
	}
	else {
		return Same(a->lchild, b->lchild)*Same(a->rchild, b->rchild);
	}
}
交换二叉树的左右子树
void Switch(BNode*& bt) {
	if (bt) {
		//采用后序遍历思想
		Switch(bt->lchild);
		Switch(bt->rchild);
		BNode* p = bt->lchild;
		bt->lchild = bt->rchild;
		bt->rchild = p;
	}
}
合并两个(升序)有序单链表
void Merge(LNode*& pa, LNode*& pb) {
	LNode* p = pa->next, * q = pb->next, * r = pa;
	while (p && q) {
		if (p->data > q->data) {
			r->next = q;
			r = q;
			q = q->next;
		}
		else {
			r->next = p;
			r = p;
			p = p->next;
		}
	}
	//链接剩余部分
	if (q) {
		r->next = q;
	}
	if (p) {
		r->next = p;
	}
}

删除单链表中拥有相同值的多余结点
void Del_Same(LNode*& pa) {
	//基本思路:一个工作指针p,两个负责删除的指针q,s
	//对于p所指向的每个结点,q、s负责遍历后续的结点,查找是否存在相同的结点
	LNode* p, * q, * s;
	for (p = pa->next; p != 0; p = p->next) {       //这里p!=0等价于p!=NULL
		for (q = p->next, s = p; q != 0;) {
			if (q->data == p->data) {
				s->next = q->next;
				free(q);
				q = s->next;
			}
			else {
				s = q;
				q = q->next;
			}
		}
	}
}
求结点x在树中的双亲结点
void parents(BNode* bt, int x) {
	//基本思路:设置队列q,采用层次遍历思想
	BNode* q[maxsize];
	int r = 0, i, flag = 0;
	BNode* p = bt;
	while (p) {
		if (p->data == x) {
			flag = 1;
			break;
		}
		else if(p->data > x) {
			q[r++] = p;
			p = p->lchild;
		}
		else {
			q[r++] = p;
			p = p->rchild;
		}
	}
	if (flag) {
		for (i = 0; i < r; i++) {
			//这里需要对每个结点的左右孩子判空,否则无法输出
			if ((q[i]->lchild && q[i]->lchild->data == x) || (q[i]->rchild && q[i]->rchild->data == x)) {
				break;
			}
		}
		if (i < r) {
			printf("结点x的双亲结点为: %d\t", q[i]->data);
		}
		else{
			printf("结点x无双亲节点\n");
		}
	}
	else {
		printf("该结点不存在\n");
	}
}
求结点在二叉树中的层次
void Layer(BNode* bt, int x) {
	//基本思路:队列+层次遍历思想
	BNode* q[maxsize];
	int r = -1, f = -1, level = 1, flag = 0;
	q[++r] = bt;
	while (r > f) {
		BNode* p = q[++f];
		if (p->data == x) {
			flag = 1;
			break;
		}
		else {
			level++;
			if (p->lchild) {
				q[++r] = p->lchild;
			}
			if (p->rchild) {
				q[++r] = p->rchild;
			}
		}
	}
	if (flag) {
		printf("结点的层次为: %d\t", level);
	}
	else {
		printf_s("不存在这样的结点\n");
	}
}
链表上实现直接插入排序
void InsertSort(LNode*& head) {
	//基本思路:设置工作指针p,负责指向无序部分的首结点,设置工作指针q,负责遍历有序部分查找合适的插入位置
	LNode* p, * q;
	int t;
	if (head == 0 || head->next == 0) {
		printf_s("链表为空");
		return;
	}
	for (p = head->next; p != 0; p = p->next) {
		for (q = head->next; q->next != p; q = q->next) {
			if (q->data > p->data) {
				t = q->data;
				q->data = p->data;
				p->data = t;
				break;
			}
		}
	}
}
统计二叉树的结点个数
//非递归
int Nodes(BNode* bt) {
	int count = 0, r = -1, f = -1;
	BNode* Q[maxsize];
	BNode* p;
	Q[++r] = bt;
	while (f < r) {
		p = Q[++f];
		count++;
		if (p->lchild) {
			Q[++r] = p->lchild;
		}
		if (p->rchild) {
			Q[++r] = p->rchild;
		}
	}
	return count;
}

//递归
int Nodes_DG(BNode* bt) {
	if (!bt) {
		return 0;
	}
	return Nodes_DG(bt->lchild) + Nodes(bt->rchild) + 1;
}
求二叉树的高度
//非递归,借助队列实现
int Height(BNode* bt) {
	int h = 0, r = -1, f = -1;
	BNode* Q[maxsize];
	BNode* p;
	Q[++r] = bt;
	while (f < r) {
		p = Q[++f];
		if (p->lchild) {
			Q[++r] = p->lchild;
			h++;
		}
		if (p->rchild) {
			Q[++r] = p->rchild;
			h++;
		}
	}
	return h;
}

//递归
int Height_DG(BNode* bt) {
	int lh, rh;
	if (!bt) {
		return 0;
	}
	lh = Height_DG(bt->lchild);
	rh = Height_DG(bt->rchild);
	return (lh > rh) ? lh + 1 : rh + 1;
}
求二叉树的WPL
int wpl = 0;
void WPL(BNode* bt, int depth) {
	if (!bt->lchild&&!bt->rchild) {
		wpl += (bt->data) * depth;
	}
	if (bt->lchild) {
		WPL(bt->lchild, depth + 1);
	}
	if (bt->rchild) {
		WPL(bt->rchild, depth + 1);
	}
}
求叶子节点个数
int End_Nodes(BNode* bt) {
	if (!bt) return 0;
	if (!bt->lchild && !bt->rchild) return 1;
	return End_Nodes(bt->lchild) + End_Nodes(bt->rchild);
}
求某一层结点的个数
int Level_Nodes(BNode* bt, int level) {
	if (level <= 0 || !bt) {
		return 0;
	}
	if (level <= 1) {
		return 1;
	}
	return Level_Nodes(bt->lchild, level - 1) + Level_Nodes(bt->rchild, level - 1);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值