1.二叉排序树的相关操作
二叉排序树的相关操作可以分为这几种:
1.创建二叉排序树
2.插入值
3.查找值
4.删除值
首先给出二叉排序树的结点类型定义:(就是一个二叉树)
struct bis {
int data;
bis* left;
bis* right;
};
因为创建二叉排序树需要用到插入值的操作,所以我们一起说:
创建二叉排序树
输入:
9
38 45 42 24 58 30 67 12 51
根据输入数据的方法不同,可以更改创建二叉排序树里面的写法,我写的这个就是按照上面的:输入第一行给出一个正整数N
;第二行给出N
个互不相同的正整数,其间以空格分隔。
每输入一个数,我们就要进行一次插入操作。
bis* creat() {
bis* root = NULL;
int n;
cin >> n;
int temp;
for (int i = 0; i < n; i++) {
cin >> temp;
root = insert(root, temp);//每输入一个数,我们就要进行一次插入操作
}
return root;
}
插入值
这个函数的第一个参数是二叉排序树的根节点,第二个参数是待插入的数据
now指针用于遍历,pre指针指向now的前驱
我这个二叉排序树是左大右小的,一般是左小右大。
当now指针为NULL时,说明pre指向了叶节点,这时候便可以插入了。
bis* insert(bis* t, int k) {
bis* pre=NULL, *now;
now = t;
while (now) {
if (k == now->data) {
return t;
}
else {
pre = now;
if (k > now->data) {//这个二叉排序树是左大右小的,一般是左小右大
now = now->left;
}
else {
now = now->right;
}
}
}
bis* newnode = (bis*)malloc(sizeof(bis));
newnode->data = k;
newnode->left = NULL;
newnode->right = NULL;
if (!t) {
t = newnode;
}
else {
if (k > pre->data) {
pre->left = newnode;
}
else {
pre->right = newnode;
}
}
return t;
}
查找值
查找值的过程和插入值的过程差不多
迭代法:
bis* search(bis* t, int k) {
bis* temp = t;
while (temp) {
if (temp->data = k) {
return temp;
}
else if (k<temp->data) {//这个二叉排序树是左大右小的
temp = temp->right;
}
else {
temp = temp->left;
}
}
return NULL;
}
递归法:
bis* search2(bis* t, int k) {
if (t == NULL || t->data == k) {
return t;
}
else {
if (k < t->data) {//这个二叉排序树是左大右小的
return search2(t->right, k);
}
else {
return search2(t->left, k);
}
}
}
删除值
删除值要注意的是待删除结点是否为根节点;
List* del(List* root, int data) {
List* now = root, * pre = NULL;//now指向待查找的结点,pre指向now的前驱
while (now&& now->data != data) {
pre = now;
if (data < now->data) {
now = now->left;
}
else {
now = now->right;
}
}
//如果找到了结点,那么会通过break跳出循环,这时now不为空,
//如果没找到,就只有当now为空时,才会退出循环。
if (!now) {
cout << "not find";
return root;
}
//如果待删除结点有左右节点
if (now->left && now->right) {
//s用来找待删除结点的中序直接后继,pres保存的是s的前驱,
//r保存的是待删除结点的中序直接后继结点的右孩子
List* pres, * s, * r;
pres = now;
s = now->right;
while (s->left) {//找出中序直接后继
pres = s;
s = s->left;
}
now->data = s->data;//中序直接后继结点替换待删除结点
r = s->right;//保存的是待删除结点的中序直接后继结点的右孩子
if (pres == now) {//如果待删除结点的右孩子没有左孩子
now->right = r;
}
else {
pres->left = r;
}
return root;
}
else {//待删除结点没有左右节点或者只有一个
List* r;//用来保存待删除结点的孩子
if (now->left) {
r = now->left;
}
else {
r = now->right;
}
if (pre == NULL) {//如果删除的是根节点
return r;//返回待删除结点的孩子
}
else if (pre->left == now) {
pre->left = r;
}
else {
pre->right = r;
}
return root;
}
}
2.判断是否为完全二叉树
判断是否为完全二叉树的方法和层序遍历差不多:
这是层序遍历:
void levelTraverse(List* root) {
queue<List*> q;
cout << root->data;
q.push(root);
List* temp;
while (!q.empty()) {
temp = q.front();
q.pop();
if (temp->left != NULL) {
cout << " " << temp->left->data;
q.push(temp->left);
}
if (temp->right != NULL) {
cout << " " << temp->right->data;
q.push(temp->right);
}
}
}
这是层序遍历的同时判断是否为完全二叉树:
bool levelTraverse(List* root) {
int flag = 1;
bool result = true;
queue<List*> q;
cout << root->data;
q.push(root);
List* temp;
while (!q.empty()) {
temp = q.front();
q.pop();
if (temp->left != NULL) {
cout << " " << temp->left->data;
q.push(temp->left);
if (flag == 0) {
result = false;
}
}
else {
flag = 0;
}
if (temp->right != NULL) {
cout << " " << temp->right->data;
q.push(temp->right);
if (flag == 0) {
result = false;
}
}
else {
flag = 0;
}
}
return result;
}
3.字符串find函数
1.find函数
语法
find(str,position)
-
str:待查找的字符串
-
position:字符串中的某个位置,表示从从这个位置开始的字符串中找指定元素(不填第二个参数,默认从字符串的开头进行查找)
返回值为目标字符的位置(第一个字符位置为0),当没有找到目标字符时返回-1
举例
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int main()
{
string message = "666acbd";
string s = "chi1 huo3 guo1";
string s2 = "ac";
int flag = message.find(s);
int flag2 = message.find(s2);
cout << flag << endl;
cout << flag2 << endl;
return 0;
}
2.find_first_of()
查找第一次出现的位置
find_last_of()
查找最后一次出现的位置
举例:
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int main()
{
string message = "string666,int m=466,34566";
string s = "66";
int first = message.find_first_of(s);
int last = message.find_last_of(s);
cout << first << endl;
cout << last << endl;
return 0;
}
3.rfind()
反向查找第一次出现的位置
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int main()
{
string message = "string666,int m=466,34566";
string s = "66";
int k = message.rfind(s);
cout << k << endl;
return 0;
}
查找所有子串在母串中出现的位置
//查找s 中flag 出现的所有位置。
string s("hello world!");
string flag="l";
int position=0;
int i=1;
while((position=s.find(flag,position))!=string::npos)
{
cout<<"position "<<i<<" : "<<position<<endl;
position++;
i++;
}
position 1 : 2
position 2 : 3
position 3 : 9