std::vector<vertex *> readDataFromHuffmanTree(vertex * source) { std::stack<vertex *> stack; std::vector<vertex *>target; while (true) { while(source->left) { stack.push(source); source = source->left; } vertex * node = new vertex; node = copyVertex(source); node->left = 0; node->right = 0; target.push_back(node); if(!stack.empty()) { source = stack.top(); stack.pop(); if (source->right) { source = source->right; } continue; } break; } return target; }
Graph copyGraph(Graph D, Graph S) { if(S->vertex != D->vertex) { DestroyGraph(D); D = intializeGraph(S->vertex); } /*必须先对每一个顶点赋值,因为图的顶点排列是通过 开放定址法的哈希表,插入顺序不同会导致顶点的序号不同*/ copyVertex(D, S); VertexType vertex1, vertex2; WeightType weight; for(int i=0; i<S->vertex; i++) { strcpy(vertex1, S->TheCells[i].vertexName); Edge edge = S->TheCells[i].next; while(edge != NULL) { weight = edge->weight; strcpy(vertex2, S->TheCells[edge->vertexIndex].vertexName); insertEdge(vertex1, vertex2, weight, D); edge = edge ->next; } } return D; }
static int clipW(const SPVertex ** _vsrc, SPVertex * _vdst) { int dsti = 0; for (int n = 0; n < 3; ++n) { const SPVertex * src1 = _vsrc[n]; // current vertex const SPVertex * src2 = _vsrc[n + 1]; // next vertex if (src1->w >= 0.01f) { copyVertex(_vdst[dsti++], src1); // add visible vertex to list if (src2->w >= 0.01f) continue; } else if (src2->w < 0.01f) continue; float a = (-src1->w) / (src2->w - src1->w); float ima = 1.0f - a; // create new vertex _vdst[dsti].x = src1->x*ima + src2->x*a; _vdst[dsti].y = src1->y*ima + src2->y*a; _vdst[dsti].z = src1->z*ima + src2->z*a; _vdst[dsti].w = 0.01f; _vdst[dsti].modify = 0; dsti++; } return dsti; }
vertex * buildHuffmanTree(std::vector<vertex *> source) { if (source.size() < 2) // Вектор содержит меньше двух элементов { return 0; } std::vector<vertex *>::iterator it; // Итератор для доступа к элементам списка while (source.size() > 1) { // Формируем дерево для формирования кодов Хаффмана /* Сортируем список в порядке возрастания вероятностей */ source = sortByChances(source); /* Выбираем две вершины с наибольшими вероятностями, формируем узел и возвращаем его в список */ vertex * insertItem = new vertex; /* Аккумулируем значения счетчиков в узле */ insertItem->count = source[0]->count + source[1]->count; /* Создаем копии указателей вершин */ vertex * left = 0; vertex * right = 0; left = copyVertex(source[0]); right = copyVertex(source[1]); /* Назначаем меньший узел левым поддеревом, больший - правым */ insertItem->left = left; insertItem->right = right; /* Удаляем из вектора выбранные вершины и вставляем новую */ it = source.begin(); source.erase(it, it + 2); source.push_back(insertItem); } vertex * root = source[0]; formHuffmanCodes(root); return root; }
/////////////////////////////////////////////////////////////////////// // Initial Run //////////////////////////////////////////////////////////////////////// void initTreeContraction (Queue* q, tree_t* tree) { int i,n; node* v; n = tree->n; currentTree = tree; initClusterList(); oldRootList.head = NULL; newRootList.head = NULL; for (i = 1; i <= n; ++i) { v = tree ->vertexArray + i; deprintf("Enqueueuing %d\n",i); insertQueue(v,q); deprintf("Making descendant copy\n"); v->descendant = copyVertex (v,currentTree->nodeList); } }
Graph maxStream(VertexType source, VertexType sink, Graph G) { Index S = findVertex(source, G); Index E = findVertex(sink, G); if(G->TheCells[S].Info != Legitimate || G->TheCells[E].Info != Legitimate) { fprintf(stderr, "vertex %s or %s does not exist", source, sink); return NULL; } /*准备好残余图和流图*/ Graph Gr = intializeGraph(G->vertex); Gr = copyGraph(Gr, G); Graph Gf = intializeGraph(G->vertex); copyVertex(Gf, G); maxStream(S, E, Gf, Gr); DestroyGraph(Gr); return Gf; }
/////////////////////////////////////////////////////////////////// // basic function that determines what to do with all nodes ////////////////////////////////////////////////////////////////// void runNode(node* thisNode, Queue* q) { int lindex,rindex; scar *lscar, *rscar; node *left=NULL,*right=NULL; deprintf("The degree is %d\n", thisNode->degree); deprintf("The cluster is %p\n",thisNode->data); deprintf("The node is %p\n", thisNode); switch (contractCheck(thisNode)) { case DO_END: setupVertexCluster(thisNode,END_EVENT, currentTree, &oldRootList); //end event the event to end them all! thisNode->vertex->cl->affected = IS_AFFECTED; deleteNode(thisNode); insertCluster(thisNode->vertex->cl,&newRootList); break; case DO_RAKE: morework =1; lindex = thisNode->left; lscar = thisNode->scars[lindex].backscar; left = GET_NEIGHBOR(lscar); doRake(thisNode,left,lindex); insertQueue(left->descendant,q); deleteNode(thisNode); break; case DO_COMPRESS: morework =1; lindex = thisNode->left; rindex = thisNode->right; lscar = thisNode->scars[lindex].backscar; rscar = thisNode->scars[rindex].backscar; left = GET_NEIGHBOR(lscar); right = GET_NEIGHBOR(rscar); doCompress(thisNode, left, right, lindex, rindex); insertQueue(left->descendant,q); insertQueue(right->descendant,q); deleteNode(thisNode); break; case DO_LIVE: { morework = 1; node *desc = thisNode->descendant; int old_degree = desc->degree; doLive(thisNode); // Queue all affected nodes. insertQueue(desc,q); deprintf("Check Undeleted \n"); // check if thisNode is un-deleted, queue neighbors if so checkUndelete(thisNode,desc); deprintf("Leaf status change \n"); // Check if leaf status of the descendant changes and queue neighbors if so checkLeafStatusChange(old_degree,desc); // Allocate a new node for the next round if needed if(!desc->descendant) { deprintf("Allocated new node \n"); desc -> descendant = copyVertex (desc,currentTree->nodeList); } } break; default: printf ("Error in runNode"); exit (-9); } }