상용 데이터 구조 도 - 토폴로지 정렬
상용 데이터 구조 도 – 토폴로지 정렬
그림.
수학 에서 하나의 그림 (Graph) 은 물건 과 물건 간 의 관 계 를 나타 내 는 수학 대상 으로 도 론의 기본 적 인 연구 대상 이다.
그림 은 매우 중요 한 데이터 구조 로 실제 생활 의 응용 에 자주 활용 된다.생활 에서 흔히 볼 수 있 는 문제, 예 를 들 어 교통 노선 도, 임무 지정 분배, 공사 기한 계산, 항공 네트워크 등 은 모두 그림 과 관련 된 이론 으로 모델 을 구축 할 수 있다.
다음은 그림 에 대한 몇 가지 정의 이다.
하나의 그림 (Graph) G = (V, E) 은 정점 (vertex) 집합 과 가장자리 (Edge) 집합 E 로 구성 된다.각 변 은 하나의 점 대 (v, w) 이 고 그 중에서 v, w 는 집합 V 에 속한다.때로는 가장자리 엣 지 를 호 (arc) 라 고도 부른다.점 쌍 이 질서 가 있다 면 그림 은 질서 가 있 는 것 (directed) 이 라 고 합 니 다.방향 이 있 는 그림 을 때때로 방향 이 있 는 그림 이 라 고 부른다.정점 v 와 w 인접 (adjacent) 이 적당 하고 (v, w) 만 E 에 속 합 니 다.변 (v, w) 을 가지 고 변 (w, v) 을 가 진 무 방향 그림 에서 w 와 v 가 인접 하고 v 와 w 도 인접 합 니 다.때로는 세 번 째 성분 을 가지 고 있 는데 권 (weight) 이나 값 (cost) 이 라 고 한다.
그림 의 저장 소
간단 한 저장 도 방식 은 인접 행렬 이 라 고 불 리 는 2 차원 배열
a[i][j]
을 사용 하고 배열 의 크기 는 n * n
이 며 n
는 그림 의 정점 개수 이다.그 중에서 정점 i 가 정점 j 로 연결 되면 a[i][j] = 1
그렇지 않 으 면 a[i][j] = 0
.이런 저장 방식 의 장점 은 간단 하고 직관 적 이 며 편리 함 을 실현 하 는 것 이다.단점 도 뚜렷 하고 필요 한 저장 공간 이 크다.n 개의 정점 을 포함 한 그림 G 의 대부분 정점 이 연결 되 지 않 으 면
n * n
인접 행렬 에 대량의 요소 가 0 이라는 것 을 의미한다. 즉, 이때 인접 행렬 은 희소 행렬 이다.또 다른 흔히 볼 수 있 는 저장 방식 은 인접 표 (adjacent list) 라 고 하 는데 이런 방식 은
n
크기 의 배열 head
, 배열 요소 head[i]
를 신청 하고 정점 i 의 모든 인접 맨 밑 으로 구 성 된 링크 의 머리 주 소 를 저장 하 는 것 이다.이런 저장 방식 의 장점 은 앞의 방식 에 비해 저장 공간의 크기 가 현저히 줄어든다.그러나 직관 적 이지 않 고 인 코딩 이 어렵 다 는 단점 이 있다.토폴로지 정렬
토폴로지 정렬 은 동그라미 가 없 는 그림 의 정점 에 대한 정렬 입 니 다.
Vi
에서 Vj
까지 의 경로 가 존재 한다 면 정렬 Vj
에서 Vi
뒤에 나타 나 야 합 니 다.간단 한 토폴로지 정렬 알고리즘 은 먼저 임의의 입 도 를 0 으로 하 는 정점 을 찾 는 것 이다.그런 후에 우 리 는 이 정점 을 출력 하고 그것 을 가장자리 와 함께 그림 에서 삭제 합 니 다.그리고 그 인접 한 정점 의 입 도 를 1 로 줄인다.그리고 상기 과정 을 반복 하면 직통 도 는 완전히 삭 제 됩 니 다.
알 수 있 듯 이 이 알고리즘 은 먼저 외층 순환
n
회 이 고 그 다음은 내부 순환 에서 입 도 를 0 으로 하 는 정점 을 선택 할 때 내부 순환 n
회 이다.따라서 전체적인 시간 복잡 도 는 n * n
에 이 를 것 이다.또 다른 좋 은 개선 방법 은 모든 입 도 를 0 인 정점 을 특정한 스 택 에 눌 러 넣 은 다음 에 매번 바닥 요소 A 를 출력 한 후에 A 의 모든 인접 정점 의 입 도 를 1 로 줄 이 는 것 이다. 만약 에 특정한 인접 정점 의 입 도 를 0 이 라면 계속 스 택 에 넣 는 것 이다.반복 상소 작업 지도 창고 비 움.
입 도 0 의 정점 마다 스 택 에 들 어 가 는 작업
n
회 를 실 행 했 고 n
은 정점 임 을 알 수 있다.스 택 에서 나 오 는 요소 A 에 대해 서 는 정점 과 인접 한 입 도 를 1 로 줄 인 다음 에 스 택 에 들 어 가 는 작업 을 최대 m
회 실 행 했 고 m
는 그림 의 개수 이다.따라서 전체적인 시간 복잡 도 는 선형 O(n)
이다.코드 예제
#include
#include
struct Node {
int value;
int indegree;
struct Node *next;
};
//
struct Node* initAdjList(int n) {
struct Node* headers;
headers = (struct Node*)malloc(sizeof(struct Node) * n);
int i = 0;
for(i; i < n; i++) {
headers[i].next = NULL;
headers[i].value = 0;
headers[i].indegree = 0;
}
return headers;
}
void addAdj(struct Node* header, int m, int n) {
struct Node* p = &header[m];
p->value++;
while(p->next != NULL)
p = p->next;
p->next = (struct Node*)malloc(sizeof(struct Node));
p->next->value = n;
p->next->next = NULL;
}
//
void printAdjList(struct Node* header, int n) {
int i = 0;
for(i; i < n; i++) {
struct Node* p = &header[i];
printf("Number of %d' adj : %d\t", i, p->value);
while(p->next!= NULL) {
printf("%d --->%d\t", i, p->next->value);
p = p->next;
}
printf("
");
}
}
//
int* topSort(struct Node* headers, int n) {
int* zeroStack = (int*)malloc(sizeof(int) * n);
int* result = (int*)malloc(sizeof(int) * n);
int count = 0;
int pIndex = -1;
int i = 0;
while(i < n) {
struct Node* p = &headers[i];
// 0,
if(p->indegree == 0)
zeroStack[++pIndex] = i;
i++;
}
while(1) {
// top Node Index
int zeroIndex = zeroStack[pIndex--];
result[count++] = zeroIndex;
struct Node* zeroNode = &headers[zeroIndex];
// zeroNode ,
while(zeroNode->next != NULL) {
struct Node* q = &headers[zeroNode->next->value];
if(--q->indegree == 0)
zeroStack[++pIndex] = zeroNode->next->value;
zeroNode = zeroNode->next;
}
//
if(pIndex < 0)
break;
}
return result;
}
int main()
{
int a[7][7] = { {0,1,1,1,0,0,0},
{0,0,0,0,1,1,0},
{0,0,0,0,0,0,1},
{0,0,1,0,0,1,1},
{0,0,0,1,0,0,1},
{0,0,0,0,0,0,0},
{0,0,0,0,0,1,0}
};
int n = 7;
struct Node* headers = initAdjList(n);
int i = 0;
int j = 0;
for(i = 0; i < n; i++)
for(j = 0; j < n; j++) {
if(a[i][j] == 1)
addAdj(headers, i, j);
}
// indegree
for(i = 0; i < n; i++) {
struct Node* p = &headers[i];
while(p->next != NULL) {
headers[p->next->value].indegree++;
p = p->next;
}
}
int* q = topSort(headers, n);
printAdjList(headers, n);
for(i = 0; i < n; i++) {
printf("%d
", *q++ + 1);
}
return 0;
}
다음으로 전송:https://www.cnblogs.com/Spground/p/8536159.html
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.