창고 와 대열 연습 문제
하나, 두 개의 창고 가 하나의 대열 을 실현 하 다
2. 두 개의 대열 이 하나의 스 택 을 실현 합 니 다.
하나, 두 개의 창고 가 하나의 대열 을 실현 하 다
분석: 스 택 은 후진 이 먼저 나 오고 대열 은 먼저 나 옵 니 다.만약 에 두 개의 스 택 으로 하나의 대열 을 실현 하려 면 주요 한 두 개의 인 터 페 이 스 는 바로 입 대 를 실현 하 는 것 이다. 그래서 우 리 는 두 개의 스 택 을 항상 하 나 를 입 대 스 택 으로 유지 하고 하 나 는 출 대 스 택 으로 구체 적 으로 아래 에서 분석 하도록 한다.
1. 정의
typedef struct QueueByTwoStack
{
Stack s1; //
Stack s2; //
}QueueByTwoStack;
2. 입단 / 출전
분석:
(1) 입 대: s1 을 입 대 스 택 으로 정의 하면 입 대 했 을 때 두 스 택 이 비어 있 는 지 없 는 지 에 관 계 없 이 s1 로 입 주 했 습 니 다.
(2) 출 대: 출 대 하려 면 두 번 째 스 택 을 빌려 야 합 니 다. 처음에 우리 가 스 택 에 들 어간 모든 데 이 터 는 s1 에 있 었 습 니 다. 만약 에 대열 의 출 대 를 실현 하려 면 s1 중의 데 이 터 를 s2 에 부 어야 합 니 다. 모든 데 이 터 를 뒤 집 었 을 때 우 리 는 s2 의 스 택 바닥 은 s1 의 스 택 이 고 s2 의 스 택 지붕 은 s1 의 스 택 바닥 이 므 로 팀 을 실현 합 니 다.바로 s2 의 스 택 을 스 택 에서 내 는 것 입 니 다. 그래서 방법 은 s2 가 비어 있 지 않 으 면 s2 스 택 의 정상 요 소 를 직접 내 면 됩 니 다.만약 s2 가 비어 있다 면, 우 리 는 s1 에 있 는 원소 의 개 수 를 제어 하여 팀 을 나 갈 수 있 으 며, 팀 을 나 간 후, s2 에 남 은 데 이 터 는 다음 팀 을 기다 리 면 된다.
void QueueByTwoStackPush(QueueByTwoStack* qts, DataType d)
{
assert(qts);
StackPush(&(qts->s1), d);
}
void QueueByTwoStackPop(QueueByTwoStack* qts)
{
assert(qts);
//1、 s2 ,
//2、 s2 , s1 ,
if (StackEmpty(&(qts->s2)) == 0)
{
while (StackEmpty(&(qts->s1)))
{
StackPush(&(qts->s2), StackTop(&(qts->s1)));
StackPop(&(qts->s1));
}
}
StackPop(&(qts->s2));
}
3. 나머지 인터페이스
void QueueByTwoStackInit(QueueByTwoStack* qts)
{
StackInit(&(qts->s1));
StackInit(&(qts->s2));
}
void QueueByTwoStackDestory(QueueByTwoStack* qts)
{
StackDestory(&(qts->s1));
StackDestory(&(qts->s2));
}
DataType QueueByTwoStackFront(QueueByTwoStack* qts)
{
//S2 ,s1
//1、 s2 , s2
//2、 s2 , , s1 ,
// s1 s2 , s2
if (StackEmpty(&(qts->s2)) == 0)
{
while (StackEmpty(&(qts->s1)))
{
StackPush(&(qts->s2), StackTop(&(qts->s1)));
StackPop(&(qts->s1));
}
}
return StackTop(&(qts->s2));
}
int QueueByTwoStackSize(QueueByTwoStack* qts)
{
return StackSize(&(qts->s1)) + StackSize(&(qts->s2));
}
int QueueByTwoStackEmpty(QueueByTwoStack* qts)
{
return StackEmpty(&(qts->s1)) | StackEmpty(&(qts->s2));
}
void TestQueueByTwoStack()
{
QueueByTwoStack qts;
QueueByTwoStackInit(&qts);
QueueByTwoStackPush(&qts, 1);
QueueByTwoStackPush(&qts, 2);
QueueByTwoStackPush(&qts, 3);
QueueByTwoStackPush(&qts, 4);
QueueByTwoStackPush(&qts, 5);
while (QueueByTwoStackEmpty(&qts))
{
printf("%d ", QueueByTwoStackFront(&qts));
QueueByTwoStackPop(&qts);
}
printf("
");
QueueByTwoStackDestory(&qts);
}
2. 두 개의 대기 열 이 하나의 스 택 을 실현 합 니 다.
분석: 첫 번 째 문 제 를 통 해 두 번 째 문 제 는 쉽게 생각 할 수 있 습 니 다. 두 대열 에서 우리 가 해 야 할 일 은 그 중의 하 나 를 항상 비 워 두 는 것 입 니 다.
1. 정의
typedef struct StackByTwoQueue
{
Queue q1;
Queue q2;
}StackByTwoQueue;
2. 입고 / 출고
분석:
(1) 입 스 택: 입 스 택 은 비 어 있 는 대기 열 에 데 이 터 를 입력 합 니 다.이 유 는 이것 이 하나의 대기 열 이기 때 문 입 니 다. 우 리 는 데이터 가 들 어 오 는 순서 만 일치 시 키 면 됩 니 다. 항상 빈 대기 열 을 유지 하 는 것 은 스 택 을 나 가기 위해 준비 하 는 것 입 니 다.
(2), 출고: 위 에서 이미 빈 대기 열 은 출고 준 비 를 위 한 것 이 라 고 말 했다.왜냐하면 이것 은 두 개의 대열 이다. 우리 가 아무리 첫 번 째 문제 처럼 거꾸로 해도 우리 가 얻 은 결 과 는 모두 같다. 팀 에 저 장 된 물건 은 변 하지 않 고 하나의 대열 을 바 꾸 어 저장 할 뿐이다.그러나 거꾸로 하 는 과정 에서 비 공 대기 열 에 남 은 데 이 터 를 발 견 했 을 때 이 데 이 터 는 바로 우리 가 스 택 에서 나 가 고 싶 은 데이터 이기 때문에 비 공 대기 열 에 있 는 데이터 개 수 를 제어 하여 스 택 에서 나 가 고 싶 은 데 이 터 를 찾 을 수 있 습 니 다.따라서 스 택 에서 두 개의 대기 열 을 정의 합 니 다. 하 나 는 빈 대기 열 을 기록 하고 하 나 는 빈 대기 열 이 아 닙 니 다.
void StackByTwoQueuePush(StackByTwoQueue* stq, DataType d)
{
assert(stq);
//1、 q1 , q1
//2、 q1 , q2
if (QueueEmpty(&(stq->q1)) != 0)
{
QueuePush(&(stq->q1), d);
}
else
{
QueuePush(&(stq->q2), d);
}
}
void StackByTwoQueuePop(StackByTwoQueue* stq)
{
Queue* empty = NULL;
Queue* nonempty = NULL;
assert(stq);
empty = &(stq->q1); //
nonempty = &(stq->q2); //
//1、 q1 , ,
if (QueueEmpty(&(stq->q1)) != 0)
{
empty = &(stq->q2);
nonempty = &(stq->q1);
}
//2、 ,
//
while (QueueSize(nonempty) > 1)
{
QueuePush(empty, QueueFront(nonempty));
QueuePop(nonempty);
}
//3、
QueuePop(nonempty);
}
3. 기타 인터페이스
void StackByTwoQueueInit(StackByTwoQueue* stq)
{
QueueInit(&(stq->q1));
QueueInit(&(stq->q2));
}
void StackByTwoQueueDestory(StackByTwoQueue* stq)
{
QueueDestory(&(stq->q1));
QueueDestory(&(stq->q2));
}
DataType StackByTwoQueueTop(StackByTwoQueue* stq)
{
// ,
//
if (QueueEmpty(&(stq->q1)))
{
return QueueBack(&(stq->q1));
}
else
{
return QueueBack(&(stq->q2));
}
}
int StackByTwoQueueSize(StackByTwoQueue* stq)
{
return QueueSize(&(stq->q1)) + QueueSize(&(stq->q2));
}
int StackByTwoQueueEmpty(StackByTwoQueue* stq)
{
return QueueEmpty(&(stq->q1)) | QueueEmpty(&(stq->q2));
}
void TestStackByTwoQueue()
{
StackByTwoQueue stq;
StackByTwoQueueInit(&stq);
StackByTwoQueuePush(&stq, 1);
StackByTwoQueuePush(&stq, 2);
StackByTwoQueuePush(&stq, 3);
StackByTwoQueuePush(&stq, 4);
StackByTwoQueuePush(&stq, 5);
while (StackByTwoQueueEmpty(&stq))
{
printf("%d ", StackByTwoQueueTop(&stq));
StackByTwoQueuePop(&stq);
}
printf("
");
StackByTwoQueueDestory(&stq);
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정수 반전Udemy 에서 공부 한 것을 중얼거린다 Chapter3【Integer Reversal】 (예) 문자열로 숫자를 반전 (toString, split, reverse, join) 인수의 수치 (n)가 0보다 위 또는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.