왕도 기 고 시리즈 - 데이터 구조
55992 단어 왕도 기 고 시리즈
창고.
예 1. 괄호 일치
예 2. 간단 한 표현 식 계산
하프 만 나무
하프 만 나무의 정의
N 개의 대 권 엽 결점 이 포 함 된 이 진 트 리 가운데 대 권 경로 길이 (WPL) 가 가장 작은 이 진 트 리 를 하프 만 트 리 라 고도 부 르 며 가장 좋 은 이 진 트 리 가 됐다.
구조 하프 만 트 리 의 알고리즘 은 다음 과 같다. 주어진 N 개의 권한 값 은 각각 w1, w2,..., Wn 의 노드 이다.(1) 이 N 개의 노드 를 각각 N 개의 나무 로 하고 하나의 노드 만 포함 하 는 이 진 트 리 로 삼림 F. (2) 를 구성 하여 새로운 노드 를 구성 하고 F 에서 두 개의 노드 의 가중치 가 가장 작은 나 무 를 새로운 노드 의 왼쪽, 오른쪽 나무 로 선택 하 며 새로운 노드 의 가중치 를 왼쪽, 오른쪽 나무 위의 노드 의 가중치 의 합 으로 한다.(3) F 에서 방금 선택 한 나무 두 그루 를 삭제 하고 새로 얻 은 나 무 를 F 에 넣는다.(4) F 에 나무 한 그루 만 남 을 때 까지 2 와 3 절 차 를 반복 한다.
하프 만 나 무 를 구성 하 는 과정 에서 작은 뿌리 더 미 를 사용 하면 O (logn) 의 시간 내 에 n 개의 원소 중 가장 작은 수 를 얻 을 수 있다.STL 의 우선 대기 열 을 빌려 다음 문장 을 이용 합 니 다.
// :
priority_queue<int, vector<int>, greater<int>> Q;
//
Q.push(x;)
//
int a = Q.top();
//
Q.pop();
예 3:
: , n, 。 , , , weight, 。
:
n;
n
:
5
1 2 2 5 9
:
37
C++ 구현:
#include
#include
#include
using namespace std;
priority_queue<int, vector<int>, greater<int> > Q;
int main() {
int n;
while(scanf("%d", &n) != EOF) {
while(!Q.empty())
Q.pop();
//
int m = 0;
for (int i = 0; i < n; i++) {
scanf("%d", &m);
Q.push(m);
}
int ans = 0;
while(Q.size() > 1) {
int a = Q.top();
Q.pop();
int b = Q.top();
Q.pop();
ans += a + b;
Q.push(a + b);
// push
}
printf("%d", ans);
}
return 0;
}
이 진 트 리
이 진 트 리 노드 의 데이터 구조:
struct TNode {
struct TNode* lchild; //
struct TNode* rchild; //
ElemType data; //
} TNode, *BiTree;
이 진 트 리 의 뒤 순 서 를 찾 아 결 과 를 옮 겨 다 니 세 요.
* * 제목: * * 이미 알 고 있 는 이 진 트 리 의 앞 순서 와 중간 순 서 를 옮 겨 다 니 며 이 진 트 리 의 뒤 순 서 를 옮 겨 다 니 는 결 과 를 구하 고 앞 순서 와 중간 순서 에 따라 이 진 트 리 를 만들어 결 과 를 출력 합 니 다.
cpp 프로 그래 밍 결과:
#include
using namespace std;
typedef struct TNode {
struct TNode* lchild; //
struct TNode* rchild; //
char data; //
} TNode, *BiTree;
BiTree CreatTree(char Pre[], char In[], int pl, int pr, int il, int ir) {
BiTree root = NULL;
root = new TNode();
root -> data = Pre[pl];
int index = 0;
for (index = il; In[index] != Pre[pl]; index++);
//
int lenl = index - il;
int lenr = ir - index;
if (lenl) {
root -> lchild = CreatTree(Pre, In, pl + 1, pl + lenl, il, il + lenl - 1);
} else {
root -> lchild = NULL;
}
if (lenr ) {
root -> rchild = CreatTree(Pre, In, pr - lenr + 1, pr, ir - lenr + 1, ir);
} else {
root -> rchild = NULL;
}
return root;
}
void PostOrder(BiTree T) {
if (T != NULL) {
PostOrder(T -> lchild);
PostOrder(T -> rchild);
printf("%c", T -> data);
}
}
void PostDeletTree(BiTree root) {
if(root != NULL) {
BiTree(root -> lchild);
BiTree(root -> rchild);
delete(root);
}
}
int main() {
char pre[26];
char in[26];
while(gets(pre) && gets(in)) {
int len = 0;
for(len = 0; pre[len] != '\0'; len++);
//
BiTree root = CreatTree(pre, in, 0, len - 1, 0, len - 1);
PostOrder(root); //
printf("
");
PostDeletTree(root); //
}
return 0;
}
두 갈래 정렬 트 리
제목: 일련의 정 수 를 입력 하고 이 진 트 리 를 만 들 고 이 진 트 리 를 앞 순서 와 뒤 순서 로 입력 합 니 다. 첫 번 째 줄 은 정수 n (0 알림: 중복 숫자 를 포함 할 수 있 습 니 다. 단일 출력 할 때 중복 숫자 를 출력 하지 않 아 도 됩 니 다.
#include
using namespace std;
typedef struct BNode {
struct BNode* lchild; //
struct BNode* rchild; //
int data; //
} BNode, *BiTree;
void PreOrder(BiTree T) {
if (T != NULL) {
printf("%d ", T -> data);
PreOrder(T -> lchild);
PreOrder(T -> rchild);
}
}
void InOrder(BiTree T) {
if (T != NULL) {
InOrder(T -> lchild);
printf("%d ", T -> data);
InOrder(T -> rchild);
}
}
void PostOrder(BiTree T) {
if (T != NULL) {
PostOrder(T -> lchild);
PostOrder(T -> rchild);
printf("%d ", T -> data);
}
}
BiTree BiSortTree(BiTree &root, int a) {
//
if (root) {
if (a < root -> data)
root -> lchild = BiSortTree(root -> lchild, a);
else if(a > root -> data)
root -> rchild = BiSortTree(root -> rchild, a);
} else {
root = new BNode();
root -> data = a;
}
return root;
}
void PostDeletTree(BiTree root) {
//
if(root != NULL) {
BiTree(root -> lchild);
BiTree(root -> rchild);
delete(root);
}
}
int main() {
int n = 0;
while(scanf("%d", &n) != EOF) {
BiTree T;
int x;
while(n--) {
scanf("%d", &x);
T = BiSortTree(T, x);
}
printf(" :");
PreOrder(T);
printf("
: ");
InOrder(T);
printf("
:");
PostOrder(T);
printf("
");
PostDeletTree(T);
}
return 0;
}
두 갈래 정렬 트 리
제목: 시작 은 n (0)
:
2
567432
543267
576342
:
YES
NO
사고: 두 갈래 정렬 트 리 의 옮 겨 다 니 는 결 과 를 비교 하여 두 나무 가 같 는 지 판단 한다.
#include
#include
using namespace std;
typedef struct BNode {
struct BNode* lchild; //
struct BNode* rchild; //
char data; //
} BNode, *BiTree;
void PreOrder(BiTree T, char po[], int &index) {
if (T != NULL) {
po[index] = T -> data;
index++;
PreOrder(T -> lchild, po, index);
PreOrder(T -> rchild, po, index);
}
}
void InOrder(BiTree T, char po[], int &index) {
if (T != NULL) {
InOrder(T -> lchild, po, index);
po[index] = T -> data;
index++;
InOrder(T -> rchild, po, index);
}
}
BiTree BiSortTree(BiTree &root, int a) {
//
if (root) {
if (a < root -> data)
root -> lchild = BiSortTree(root -> lchild, a);
else if(a > root -> data)
root -> rchild = BiSortTree(root -> rchild, a);
} else {
root = new BNode();
root -> data = a;
}
return root;
}
void PostDeletTree(BiTree root) {
//
if(root != NULL) {
BiTree(root -> lchild);
BiTree(root -> rchild);
delete(root);
}
}
int main() {
int n = 0;
while(scanf("%d", &n) != EOF && n != 0) {
BiTree T = NULL;
char old[10] = {'\0'};
char pold[10] = {'\0'};
char iold[10] = {'\0'};
char str[10] = {'\0'};
char pstr[10] = {'\0'};
char istr[10] = {'\0'};
int index = 0;
scanf("%s", old);
int i = 0;
for (i = 0; old[i] != '\0'; i++)
T = BiSortTree(T, old[i]);
index = 0;
PreOrder(T, pold, index);
index = 0;
InOrder(T, iold, index);
PostDeletTree(T);
for (int j = 0; j < n; j++) {
//
BiTree NT = NULL;
for (int l = 0; l < n; l++) {
str[l] = '\0';
pstr[l] = '\0';
istr[l] = '\0';
}
scanf("%s", str);
for (int k = 0; str[k] != '\0'; k++)
NT = BiSortTree(NT, str[k]);
index = 0;
PreOrder(NT, pstr, index);
index = 0;
InOrder(NT, istr, index);
if (strcmp(pold, pstr) == 0 && strcmp(iold, istr) == 0)
printf("YES
");
else
printf("NO
");
PostDeletTree(NT);
}
printf("please input the number n: ");
}
return 0;
}