Autor: Fuente: 4 de septiembre de 2006
13. Coloque el centinela en R[n] y ordene los registros que se colocan en R. [0..n-1] y se reescribe el algoritmo de clasificación por inserción directa.
Solución:
El algoritmo reescrito es el siguiente:
void InsertSort(SeqList R)
{//Insertar y ordenar registros r [0...n-1] en orden ascendente.
int i, j;
for(I = n-2; i gt=0; I-)//Insertar R[n-2]..R[0] secuencialmente en la región ordenada.
if(R[i].key gtR[i 1].key) //Si no, R[i] permanece sin cambios.
{
R[n]= R[I]; j = I 1; //R[n] es el centinela
Do{ // Desde Encuentra la posición de inserción en un rango ordenado de izquierda a derecha.
R[j-1]= R[j]; //Mover registros con palabras clave menores que R[i]. La clave está a la derecha.
j;
}mientras(R[j].key ltR[n].key]);
R[j-1]= R[ n]; //Inserta R[i] en la posición correcta.
}//endif
}//InsertSort.
14. Utilice una lista enlazada individualmente como estructura de almacenamiento para implementar el algoritmo de clasificación por inserción directa.
Solución:
#define int KeyType //Definir KeyType como tipo int.
nodo de estructura typedef {
KeyType key; //campo de palabra clave
Otro tipo de información información; //Otro campo de información,
Nodo de estructura * siguiente//Campo puntero en la lista vinculada
} RecNode//Tipo de nodo de registro
typedef RecNode * LinkList//Una única lista vinculada está representada por LinkList.
void InsertSort (encabezado de lista vinculada)
{// Algoritmo de clasificación por inserción directa para una estructura de almacenamiento vinculada, donde el encabezado es una lista individualmente vinculada con el nodo principal como unidad.
RecNode *p, *q, *s;
if ((head- gt; next) amp amp (head- gt; next- gt; next))/ // Cuando el número de nodos en la tabla es mayor que 1.
{
p = head- gt; next- gt; // p apunta al segundo nodo.
head->; next = NULL
q = head; // Apunta al nodo anterior en la posición de inserción.
mientras(p) amp(pregunta->;siguiente) amp amp(p->;key ltq->;next-gt;key)
q = q- gt; siguiente;
If (p)
{ s = p; p = p- gt;
s- gt; next = q- gt; //Inserta la posición apropiada después del nodo Q
q->; >}
}
}
15. Diseñar un algoritmo para reorganizar la matriz en el menor tiempo posible y colocar todas las palabras clave negativas antes que todas las no negativas. palabras clave. Analice la complejidad temporal del algoritmo.
Solución:
Debido a que solo las palabras clave negativas deben clasificarse en primer lugar y no existe un orden de clasificación preciso, este algoritmo utiliza un método de escaneo en ambos extremos, al igual que rápido. El mismo método es utilizado en la clasificación. Cuando se escanea un número positivo hacia la izquierda, se detiene el escaneo hacia la derecha. Cuando se encuentra un número negativo, se intercambia con el registro actual a la izquierda, de modo que la clasificación se pueda completar en un solo viaje.
Recurso no válido (SeqList R)
{//Reorganice la matriz para que la palabra clave negativa ocupe el primer lugar.
int i=1, j = n; //La matriz se almacena en r [1...n]
while(i ltj) //I j significa; que el escaneo aún no ha finalizado.
{ while(I lt; Johnson & Johnson. ampR[i]. key lt0) //Si se encuentra un número negativo, continúe escaneando.
i;
R[0]= R[I]; //R[0] es un espacio auxiliar.
while(i lt Johnson & Johnson. ampR[j]. key gt=0)//Si se encuentra un número positivo, continúe escaneando hacia la izquierda.
j-;
R[i]= R[j]; R[j-]= R[0]; // Intercambia los dos elementos actuales y mueve el puntero.
}//Hora de finalización
}//Resort
En cualquier caso, el número de comparaciones en este algoritmo es n (0 para cada elemento), el número de intercambios es menor que n/2. En términos generales, la complejidad del tiempo es O (n).
*16. Escriba un algoritmo de clasificación de burbujas bidireccional, que cambie alternativamente la dirección de escaneo durante el proceso de clasificación.
Solución:
El algoritmo es el siguiente:
clasificación de burbujas vacías (SeqList R)
{//r [1. .n] es el archivo que se va a ordenar mediante la clasificación de burbujas de escaneo bidireccional.
int i, j, k;
intercambio booleano; //etiquetas de intercambio
I = n; intercambio=true;
mientras(I gt; j) amp; amp(intercambio)
{ k = I-1; intercambio=false;
mientras (k gt; = j) //Escanear de abajo hacia arriba
{ if(r[k] gt; r[k 1])
{ r[0]= r [k]; r[k] = r[k 1]; r[k 1] = r[k]; intercambio = verdadero; // intercambio
}//endif
k-;
}//hora de finalización
if (intercambio)
{ intercambio = FALSE
j; 1;
while(k lt;=i)//Escanear de arriba a abajo
{ if(r[k] lt; r[k-1])
{ r[0]= r[k]; r[k]= r[k-1]; r[k-1]= r[k]; intercambio=true;
}//endif
k;
}Hora de finalización
I-;
}//endif
}Hora de finalización
}//endsort
17. El siguiente es un algoritmo de pseudocódigo para la clasificación de burbujas de arriba hacia abajo, que utiliza lastExchange para registrar los intercambios en cada escaneo. La posición del último elemento se utiliza como valor de control para la terminación del siguiente ciclo de clasificación. Escriba un algoritmo de clasificación de burbujas de escaneo ascendente.
void BubbleSort(int A[], int n)
//Sea A[0..n-1] un vector entero.
int lastExchange, j, I = n-1
mientras(I gt; 0)
último intercambio = 0
for(j = 0; j lt i; J) //Escanee A[0..i] de arriba a abajo.
if(A[j 1] lt;A[j]){
Intercambio A[j] y A[j 1];
último intercambio = j;
}
i = lastExchange//Establece I en la última posición de intercambio.
}//Hora de finalización
}//BubbleSort
Solución: El algoritmo es el siguiente:
void BubbleSort(int A [] , int n)
//Sea A[0..n-1] un vector entero.
int lastExchange, j, I = 0;
while(i ltN) //Esto es muy importante. Si esto no se cambia, el algoritmo se repetirá infinitamente.
último intercambio = n;
for(j = n-1;j gti;j-)//Escanee A[0..i] de abajo hacia arriba.
if(A[j-1] lt;A[j]){
Intercambia A[j] y A[j-1];
último intercambio = j;
}
i = lastExchange//Establece I en la última posición de intercambio.
}//Hora de finalización
}//BubbleSort
18. Para reescribir la clasificación rápida, debe seleccionar los registros de referencia para la división seleccionando tres; Si la longitud del intervalo actualmente ordenado es menor o igual a 3, la clasificación por inserción se realiza directamente sin dividir.
Solución:
El algoritmo reescrito es el siguiente:
clasificación rápida nula (SeqList R, int low, int high)
{//Ordenar R [bajo...alto] rápidamente
int pivotpos
if (alto-bajo lt=2)//Si hay menos de 3 elementos en el actual área,
{//Realizar ordenación por inserción directa.
InsertSort(R, bajo, alto);
}
Otro
{
pivote pos = partición media(R, baja, alta);
QuickSort(R, baja, pivote pos-1);
QuickSort(R, pivotpos 1, alta);
}
}//Clasificación rápida
int mid particion(seq list R, int i, int j)
{//Con los tres Las reglas son la base.
if(R[(i j)/2].key gtR[i].key)
{Intercambiar R[(i j)/2] y R[I];}
if(R[i].key gtR[j].key)
{Intercambiar R[i] y R[j];}
if (R[i].tecla) ltR[(i j)/2]. Clave)
{Exchange R[i] y R[(I j)/2];}
//Las tres declaraciones if anteriores constituyen el primer registro en el intervalo La clave El valor se convierte en el valor medio de las tres claves.
Parte de retorno (R, I, j); // Entonces todavía podemos usar el algoritmo de división original.
}
19. Para un j dado (1≤j≤n), se requiere encontrar el j-ésimo en el área de registro desordenado R[1 según la palabra clave de de pequeño a grande. Registro de posición..n] (es decir, encuentre el jésimo elemento más pequeño en un conjunto desordenado) e intente escribir un algoritmo utilizando la idea de división de clasificación rápida para implementar la operación de búsqueda anterior.
Respuesta:
int quick sort (SeqList R, int j, int low, int high)
{//Sort R [bajo...alto ]Rápidamente
int pivotpos//La posición del registro de referencia dividido
if (low ltHigh){//Solo se ordena cuando la longitud del intervalo es mayor que 1.
pivotpos=Partition(R, low, high); //División de frecuencia R[low...high]
if (pivotpos==j) devuelve r[j];
else if(pivot pos gt;j) return(R,j,low,pivotpos-1);
else return quicksort(R,j,pivotpos 1,high);
}
}//Clasificación rápida
20. Escriba un algoritmo de clasificación de selección directa utilizando una lista enlazada individualmente como estructura de almacenamiento.
Respuesta:
#define int KeyType //Definir KeyType como tipo int.
nodo de estructura typedef {
KeyType key; //campo de palabra clave
Otro tipo de información información; //Otro campo de información,
Nodo de estructura * siguiente//Campo puntero en la lista vinculada
} RecNode//Tipo de nodo de registro
typedef RecNode * LinkList//Una única lista vinculada está representada por LinkList.
void selectsort (encabezado de lista vinculada)
{RecNode *p, *q, *s;
if(head- gt; next) amp amp( head-gt;next-gt;next)
p = head-gt;next; //p apunta al predecesor del elemento más grande en el orden de clasificación actual.
mientras(p->; siguiente)
{ q = p- gt; siguiente;
mientras(q)
p>{ if(q- gt; key lts- gt; key)s = q;
q = q- gt;
}//Hora de finalización
Intercambiar datos del nodo S y del nodo P;
p = p- gt; Siguiente;
}//Hora de finalización
}//endif
}//endsort
21. Escriba un algoritmo heapInsert(R, key) para insertar la clave en el montón R para asegurarse de que todavía esté en el montón. después de insertar R. Consejo: se debe agregar una descripción del atributo de longitud al montón R (es decir, la descripción del tipo de SeqList definida en este capítulo debe reescribirse para incluir el campo de longitud; la clave debe insertarse al final del campo); elementos existentes en R (es decir, la longitud del montón original más La posición superior es 1, agregue 1 a la longitud del montón insertado y luego ajuste de abajo hacia arriba para que la palabra clave insertada cumpla con los atributos. Analice el tiempo del algoritmo.
Respuesta:
#define n 100//Supongamos que la longitud del archivo es lo más larga posible.
typedef int KeyType//Defina KeyType como tipo int.
nodo de estructura typedef {
KeyType key; //campo de palabra clave
Otro tipo de información información; //Otro campo de información,
} Rectype//Tipo de nodo de registro
estructura typedef {
Rectype data[n]; //Espacio para almacenar registros
int length;
} seqlist
void heapInsert(seqlist *R, KeyType key)
{//El elemento del montón original está en r->; ~ R- gt; datos [R- gt; longitud],
// Inserte la nueva clave de palabra clave en la posición R- gt; p >// Con R- gt; Data[0] es un espacio auxiliar, ajustado a un montón (aquí establecido en un montón raíz grande).
int large//large apunta a la palabra clave más grande entre los nodos secundarios izquierdo y derecho del nodo de ajuste.
int low, high; //low y high apuntan respectivamente al primer y último registro del montón que se va a ajustar.
int I;
r- gt; longitud; r- gt; datos [R- gt; clave = clave//Insertar nuevo registro
for(I = R- gt; length/2; I gt0; I-)//Construir un montón
{
bajo = I; alto = R- gt;
r- gt; clave = R- gt;datos[bajo]. Key; //R-gt; Data[low] es el nodo actualmente ajustado.
for(large=2*low; large lt=high; large*=2){
//Si gt grande alto significa R- gt; los datos [bajos] son A hoja, el ajuste ha terminado;
// De lo contrario, apunte el puntero grande a R- gt el hijo izquierdo de los datos [bajo]
if(large lt; high amp; ampr- gt; data [big].key ltr-gt;data[big1].key)
Large; //Si el hijo derecho de R-gt;data[low] existe.
//Y la palabra clave es mayor que la hermana izquierda, dale mucha importancia.
if(R- gt; datos[0]. clave ltr- gt; datos[grande]. clave)
{ R- gt; datos[bajo]. clave = R- gt;datos[grande]. Key;
Low=Large; //Haga que el punto bajo apunte al nuevo nodo de ajuste.
}
else break//El nodo de ajuste actual no es menor que la palabra clave de su nodo secundario y el ajuste se completa.
}//Fin
r- gt; datos [bajos]. clave = R-gt;datos[0]. Clave; // Coloca el nodo ajustado en la última posición.
}Fin de //
} Fin de inserción del montón
Análisis del algoritmo:
Si la longitud del archivo es n, el algoritmo debe ajustarse en n /2 pasadas, la complejidad de tiempo total es similar a la del montón inicial, la peor complejidad de tiempo es O (nlgn) y el espacio auxiliar es O (1).
22. Escriba un algoritmo de construcción de montón: comience desde un montón vacío, lea los elementos en secuencia, llame al algoritmo de inserción del montón en la pregunta anterior e inserte elementos en el montón.
Respuesta:
void BuildHeap(seqlist *R)
{
Clave KeyType;
r- gt; length = 0; // Genera un montón vacío
scanf("d", amp key); // Establece MAXINT en la palabra clave imposible.
Y (key!=MAXINT)
{
heapInsert(R, key);
scanf("d ", amp Key);
}
}
23 Escriba un algoritmo de eliminación del montón: HeapDelete (R, I), elimine R [i] del montón, Analizar tiempos de algoritmo. Sugerencia: primero intercambie R [i] con el último elemento del montón, reduzca la longitud del montón en 1 y luego ajuste hacia abajo desde la posición I para cumplir con las propiedades del montón.
Respuesta:
void HeapDelete(seqlist *R, int i)
{//El elemento del montón original está en r->; ~ R - gt; datos [R- gt; longitud],
//put R- gt; datos [i], es decir, R->; se pone en R- gt;Después de los datos [i],
//poner R- gt;La longitud se resta en 1 y luego se ajusta el montón.
// Con R- gt; Data[0] es un espacio auxiliar, ajustado a un montón (aquí establecido en un montón raíz grande).
int large//large apunta a la palabra clave más grande entre los nodos secundarios izquierdo y derecho del nodo de ajuste.
int low, high; //low y high apuntan respectivamente al primer y último registro del montón que se va a ajustar.
int j;
if(i gtr- gt; longitud)
error("no existe tal nodo");
r - gt;datos[i]. clave = R- gt; datos [R- gt longitud]. clave;
r- gt; longitud-; r- gt; datos [R- gt; clave = clave//Insertar nuevo registro
for(j = I/2;j gt0;j-)//Construir un montón
{
Bajo = j; altura = R-gt; longitud;
r-gt; clave = R- gt;datos[bajo]. Key; //R-gt; Data[low] es el nodo actualmente ajustado.
for(large=2*low; large lt=high; large*=2){
//Si gt grande alto significa R- gt; los datos [bajos] son A hoja, el ajuste ha terminado;
// De lo contrario, apunte el puntero grande a R- gt el hijo izquierdo de los datos [bajo]
if(large lt; high amp; ampr- gt; data [big].key ltr-gt;data[big1].key)
Grande; //Si el hijo derecho de R-gt;data[low] existe.
//Y la palabra clave es mayor que la hermana izquierda, dale mucha importancia.
if(R- gt; datos[0]. clave ltr- gt; datos[grande]. clave)
{ R- gt; datos[bajo]. clave = R- gt;datos[grande]. Key;
Low=Large; //Hacer que el punto bajo apunte al nuevo nodo de ajuste.
}
else break//El nodo de ajuste actual no es menor que la palabra clave de su nodo secundario y el ajuste se completa.
}//Fin
r- gt; datos [bajos]. clave = R-gt;datos[0].
Clave; // Coloca el nodo ajustado en la última posición.
}Fin de //
} Fin de eliminación del montón
24 Supongamos que los elementos de las dos listas enlazadas individualmente están organizados en orden ascendente, intente. escribir un algoritmo para fusionar estas dos listas vinculadas ordenadas en una única lista vinculada en orden ascendente. El algoritmo debe utilizar el espacio de nodos de la lista enlazada original.
Respuesta:
nodo de estructura typedef {
KeyType key; //Campo de palabra clave
Otro tipo de información //Otra información; campo,
Nodo de estructura * siguiente//Campo de puntero en la lista vinculada
} RecNode//Tipo de nodo de registro
typedef RecNode * LinkList//Lista vinculada única Representado por LinkList.
Clasificación de combinación no válida (lista vinculada la, lista vinculada lb, lista vinculada lc)
{RecNode *p, *q, *s, *r;
lc = la
p = la//p es el puntero de escaneo de la tabla la, que apunta a la posición anterior del nodo a comparar.
q=lb->Next; //q es el puntero de escaneo de la tabla lb, que apunta al nodo comparado.
while(p->; next) amp amp(pregunta)
if (p->; next-gt; key lt= q->; key)
p>
p = p- gt; siguiente;
else { s = q; q- gt;
siguiente = p - gt; next; p->; next = s; // Después de insertar el nodo S en el nodo P,
p = s; >; Siguiente) p- gt; next = q;
Libre (libra);
}
25. 1 ] contiene n números enteros diferentes, cada elemento tiene un valor entre 0 y n-1. Intente escribir un algoritmo de tiempo O (n) para ordenar el vector A y el resultado se puede enviar a otro vector B [0..n-1].
Respuesta:
sort(int *A, int *B)
{//Ordena el vector A y envíalo al vector b.
int I;
for(I = 0; i lt= n-1; i)
b[A[I]]= A[I ];
}
*26. Escribe un algoritmo de clasificación de bases para un conjunto de palabras en inglés ordenadas en el diccionario. Deje que todas las palabras consten de letras mayúsculas y que la palabra más larga tenga d letras. Consejo: Todas las palabras con una longitud inferior a d letras deben completarse con espacios al final. Al ordenar, se deben configurar 27 cuadros, correspondientes a espacios, a, B...z respectivamente.
Respuesta:
#define KeySize 10 //Establece el número de dígitos de la palabra clave d=10.
#Definir base 27 //La base rd es 27.
typedef Tipo de datos RecType; //Cambia el tipo de datos del nodo en la cola al tipo RecType.
nodo de estructura typedef {
char key[KeySize]; //Campo de palabra clave
Otra información de tipo de información //Otros campos de información,
} RecType//Tipo de nodo de registro
typedef RecType seqlist[n 1];
clasificación por radio vacío
{
cola de enlace B[base];
int I;
for(I = 0; I lt base; I)//El cuadro está vacío
init queue(amp;b[I]);
for(I = KeySize-1;i gt=0;I-){//Ordenar los cuadros D-trip de menor a mayor.
Distribute(R, B, I); //La primera distribución de transferencia KeySize-i
Collect(R, B); //La primera colección KeySize-i
>}
}
void Distribute(seqlist R, LinkQueue B[], int j)
{//Según la palabra clave The jth El componente está asignado y el primer cuadro está vacío.
int I;
j = KeySize-j; // Determina la posición de la palabra clave comenzando desde el bit bajo.
for(I = 0;i ltn;I) //Escanee R[i] en secuencia y encárguelo.
if (R[i].Key[j]-' A 'gt; 26)
queue(ampB[0],R[I]); //Coloca el Los espacios de palabras clave j se registran en la cola 0.
De lo contrario, cola (ampB[0], R[R[i]. key[j]-' A ' 1]); Collect(seqlist R, LinkQueue B[])
{
//Recoja los registros en cada cuadro no vacío por turno. Después de este proceso, todos los cuadros estarán vacíos.
int i, j;
for(j = 0; j lt base; j )
mientras (!cola vaciada (ampB[j])
r[i]=dequeue (ampb[j]); //Envía los registros fuera de cola a R[i] en secuencia
}
.