c語言重建
1. c語言數據結構 堆的建立和維護
主要函數功能:1、通過輸入的數組,建立堆結構
2、將堆結構按小頂堆排列
3、輸入POP命令提取一個頂元素,存放在數組中。
(刪除頂節點,重新初始化堆結構,重新按小頂堆排列)
4、輸入PUSH命令將一個數值插入到堆末尾。
(新數值插入數組末尾,用新數組重建堆,重新按小頂堆排列)
5、列印所有POP提取的頂元素
#include<stdio.h>
#include<malloc.h>
#include<string.h>
typedefstructnode
{
int*data;
structnode*left;
structnode*right;
structnode*brother;
structnode*father;
}NODE;
typedefstructheapTree
{
intsize;
int*nums;//節點數值對應的數組
NODE**nodes;//所有的節點指針,用於釋放堆
structnode*rootNode;//根節點
structnode*lastNode;//從上往下,從左往右數最後一個節點
}HEAP;
HEAP*initHeap(int*nums,intsize);//初始化堆
voidrecom(NODE*lastNode,intb);//重組堆,按小頂堆排列。先和子女比較,再兄弟和子女比較,再父親和子女比較。
//參數:lastNode最後一個節點;b避免兄弟間無限循環,b=2跳出兄弟,進行父親與子女比較,首次調用b傳值1
voidprintfHeap(NODE*rootNode);//測試調試使用:遍歷並列印堆數值
voidfreeHeap(HEAP*heap);//釋放堆內存
intgetRootNode(HEAP*heap);//取出頂元素
voidaddRootNode(HEAP*heap,intnum);//插入節點元素
intmain()
{
inti,m,n,*nums=NULL,*rootNums=NULL,rNumSize=0,xwNum;//xwNum詢問數值
charxwStr[5];//詢問字元串POP或PUSH
HEAP*heap=NULL;
printf("輸入n,m的值:
");
scanf("%d%d",&n,&m);
nums=(int*)malloc(sizeof(int)*n);
printf("輸入%d個數字:
",n);
for(i=0;i<n;i++)
scanf("%d",&nums[i]);
heap=initHeap(nums,n);
recom(heap->lastNode,1);
//printfHeap(heap->rootNode);//測試:順序列印節點
printf("等待%d次詢問,請輸入POP或PUSH命令:
",m);
while(1)
{
scanf("%s",xwStr);
if(strcmp(xwStr,"POP")==0)
{
rNumSize++;
if(rootNums==NULL)
rootNums=(int*)malloc(sizeof(int)*rNumSize);
else
rootNums=(int*)realloc(rootNums,sizeof(int)*rNumSize);//擴展原取值的存儲內存
rootNums[rNumSize-1]=getRootNode(heap);//取出頂元素
//printfHeap(heap->rootNode);//測試:順序列印節點
}
elseif(strcmp(xwStr,"PUSH")==0)
{
scanf("%d",&xwNum);
addRootNode(heap,xwNum);//插入新元素
//printfHeap(heap->rootNode);//測試:順序列印節點//插入後重新排序有問題
}
m--;
if(m==0)
break;
}
printf("所有取出的頂端數值為:
");
for(i=0;i<rNumSize;i++)
printf("%d",rootNums[i]);
printf("
");
return0;
}
voidaddRootNode(HEAP*heap,intnum)//插入節點元素
{
inti,*numsSave=NULL,*nums=heap->nums,size=heap->size;
numsSave=(int*)malloc(sizeof(int)*(size+1));
for(i=0;i<size;i++)
numsSave[i]=nums[i];
nums=NULL;
numsSave[i]=num;//將新元素添加在數組末尾
freeHeap(heap);//釋放堆內存
heap=initHeap(numsSave,size+1);//重新初始新的堆
recom(heap->lastNode,1);//重新小頂堆排列
}
intgetRootNode(HEAP*heap)//取出頂元素
{
inti,*numsSave=NULL,*nums=heap->nums,size=heap->size,rootNum;
rootNum=*heap->rootNode->data;
*heap->rootNode->data=nums[size-1];//根節點對應值換成數組最後一位地址值
numsSave=(int*)malloc(sizeof(int)*(size-1));
for(i=0;i<size-1;i++)
numsSave[i]=nums[i];
nums=NULL;//原數組空間將在freeHeap函數中一並釋放
freeHeap(heap);//釋放堆內存
heap=initHeap(numsSave,size-1);//重新初始新的堆
recom(heap->lastNode,1);//重新小頂堆排列
returnrootNum;
}
voidfreeHeap(HEAP*heap)//釋放堆內存
{
inti;
for(i=0;i<heap->size;i++)//釋放所有節點空間
{
heap->nodes[i]->data=NULL;
heap->nodes[i]->brother=NULL;
heap->nodes[i]->father=NULL;
heap->nodes[i]->left=NULL;
heap->nodes[i]->right=NULL;
free(heap->nodes[i]);
}
free(heap->nums);
heap->nums=NULL;
heap->nodes=NULL;
heap->lastNode=NULL;
heap->rootNode=NULL;
heap->size=0;
free(heap);
}
voidprintfHeap(NODE*rootNode)//遍歷並列印堆數值
{
printf("%d",*rootNode->data);
if(rootNode->father==NULL&&rootNode->left!=NULL)//根節點
printfHeap(rootNode->left);
elseif(rootNode->father->left==rootNode&&rootNode->father->right!=NULL)//如果第左,那麼找右
printfHeap(rootNode->father->right);
elseif(rootNode->father->right==rootNode&&rootNode->brother->left!=NULL)//如果第右,那麼找左的左兒子
printfHeap(rootNode->brother->left);
else
printf("
");
}
HEAP*initHeap(int*nums,intsize)
{
inti;
NODE*newNode=NULL;
HEAP*heap=(HEAP*)malloc(sizeof(HEAP));
heap->rootNode=NULL;
heap->lastNode=NULL;
heap->nodes=(NODE**)malloc(sizeof(NODE*)*size);
heap->nums=nums;
for(i=0;i<size;i++)
{
newNode=(NODE*)malloc(sizeof(NODE));
heap->nodes[i]=newNode;
newNode->data=&nums[i];
newNode->left=NULL;
newNode->right=NULL;
newNode->brother=NULL;
newNode->father=NULL;
if(heap->rootNode==NULL)
heap->rootNode=newNode;
elseif(heap->lastNode->father==NULL)//上一個節點為根節點沒有兄弟,新節點放在左位置
{
heap->lastNode->left=newNode;
newNode->father=heap->lastNode;
}
elseif(heap->lastNode->father->left==heap->lastNode)//上一個非根左節點,新節點放兄弟位置
{
heap->lastNode->brother=newNode;
newNode->brother=heap->lastNode;
newNode->father=heap->lastNode->father;
newNode->father->right=newNode;
}
elseif(heap->lastNode->father->right==heap->lastNode)//上一個非根右節點,新節點放兄弟左兒子位置
{
heap->lastNode->brother->left=newNode;
newNode->father=heap->lastNode->brother;
}
heap->lastNode=newNode;
}
heap->size=size;
returnheap;
}
voidrecom(NODE*lastNode,intb)//重組堆,按小頂堆排列。先和子女比較,再兄弟和子女比較,再父親和子女比較。
//參數:lastNode最後一個節點;b避免兄弟間無限循環,b=2跳出兄弟,進行父親與子女比較
{
intnumSave;
NODE*minNode=NULL,*fNode=lastNode->father,*bNode=lastNode->brother,*lNode=lastNode->left,*rNode=lastNode->right;
if(lNode!=NULL)
{
minNode=lastNode;
if(*minNode->data>*lNode->data)
{
numSave=*minNode->data;
*minNode->data=*lNode->data;
*lNode->data=numSave;
}
}
if(rNode!=NULL)
{
if(*minNode->data>*rNode->data)
{
numSave=*minNode->data;
*minNode->data=*rNode->data;
*rNode->data=numSave;
}
}
if(b==2)
recom(fNode,1);
elseif(bNode!=NULL)
recom(bNode,2);
}
2. c語言\r什麼意思
\r是回車符,\n是換行符。
計算機還沒有出現之前,有一種叫做電傳打字機(Teletype Model 33)的玩意,每秒鍾可以打10個字元。但是它有一個問題,就是打完一行換行的時候,要用去0.2秒,正好可以打兩個字元。要是在這0.2秒裡面,又有新的字元傳過來,那麼這個字元將丟失。
於是,研製人員想了個辦法解決這個問題,就是在每行後面加兩個表示結束的字元。一個叫做「回車」,告訴打字機把列印頭定位在左邊界;另一個叫做「換行」,告訴打字機把紙向下移一行。
這就是「換行」和「回車」的來歷,從它們的英語名字上也可以看出一二。
後來,計算機發明了,這兩個概念也就被般到了計算機上。那時,存儲器很貴,一些科學家認為在每行結尾加兩個字元太浪費了,加一個就可以。於是,就出現了分歧。Unix 系統里,每行結尾只有「<換行>」,即「\n」;Windows系統裡面,每行結尾是「<回車><換行>」,即「 \r\n」;Mac系統里,每行結尾是「<回車>」。一個直接後果是,Unix/Mac系統下的文件在Windows里打開的話,所有文字會變成一行;而Windows里的文件在Unix/Mac下打開的話,在每行的結尾可能會多出一個^M符號。
3. C語言編譯後顯示沒有這樣的文件或目錄是什麼意思
最好上個截圖,應該是庫文件的路徑設置不對。通常在集成環境的選項中有連接文件庫的路徑設置。
4. c語言問題
在 VC6.0 中新建一個工程,添加 fun.c、main.c 兩個源文件和 fun.h 一個頭文件,內容如下:
fun.c
#include <stdio.h>
int fun1(){
printf("The first function!\n");
return 0;
}
int fun2(){
printf("The second function!\n");
return 0;
}
int fun3(){
printf("The third function!\n");
return 0;
}
fun.h
#ifndef _FUN_H
#define _FUN_H
extern int fun1(void);
extern int fun2(void);
extern int fun3(void);
#endif
main.c
#include <stdio.h>
#include <stdlib.h>
#include "fun.h"
int main(){
fun1();
fun2();
fun3();
system("pause");
return 0;
}
對上面的每個 .c 文件都進行編譯,然後鏈接並運行:
The first function!
The second function!
The third function!
上面的例子,函數定義放在 fun.c 文件中,在 fun.h 頭文件中對函數進行聲明,暴露介面,然後在主文件 main.c 中引入 fun.h。
注意:編譯是針對單個 .c 文件的,如果項目中有多個 .c 文件,需要逐一編譯,然後鏈接,或者使用「組建 -> 全部重建」選項,一次性編譯並鏈接所有文件。
多文件編程時,只能有一個文件包含 main() 函數,因為一個工程只能有一個入口函數。我們把包含 main() 函數的文件稱為主文件。
可以在其他 .c 文件中對函數進行定義,在 .h 中對函數進行聲明,只要主文件包含進相應的頭文件,就能使用這些函數。實際開發中,很少有簡單到只有幾十行代碼的C語言項目,合理的組織代碼和文件,是開發大中型項目的必備技能。
為了更好的組織各個文件,一般情況下一個 .c 文件對應一個 .h 文件,並且文件名要相同,例如 fun.c 和 fun.h。如果 fun.c 使用到了 fun.h 的宏定義、類型定義等,還需要在 fun.c 中 #include "fun.c"。
.c 文件主要包含各個函數的定義,.h 文件聲明函數原型,向外暴露介面,供主文件調用。另外也可以在 .h 中包含宏定義、類型定義。
注意:.h 文件頭文件中不能有可執行代碼,也不能有變數定義,只能有宏、類型( typedef,struct,union,menu )定義和變數、函數的聲明。
這倒不是說在 .h 中定義變數或函數會有語法錯誤,實際上#icnlude機制很簡單,就是把#include所包含的文件中的內容直接復制到#include所在的位置並替換#include語句。但是這樣做不符合模塊化編程的慣例,也不利於文件的組織,不利於二次開發,不利於團隊協作。
以上是網上找來的。
實際上只要一個工程裡面有多個文件,那麼都會編譯到。
5. 這種c語言怎麼處理
這段條件語句,應寫成:
if (a!=b){
if (a>b) printf("A>B\n"); else printf("A<B\n");
} else printf("A=B\n");
----------
至於編譯錯誤,要看到完整程序才行。因涉及 main () 的問題和變數重復定義問題,它們有可能是 花括弧 配對出錯引起,也可能有別的問題。
6. c語言大師 看一下 編譯成功 無法創建目標
你這個文件叫什麼名字? 錯誤中顯示你的工程裡面有兩個主函數。
還有一個是lsq.c裡面的。
你查一下是不是重復文件了。
不行的話,關掉project 然後重建一個。
7. 怎樣在c語言中修改已錄入的文件信息,謝謝
用FILE定義文件指針
FILE
*fp;
fp=fopen("文件名","a");//往原文件追加數據
fp=fopen("文件名","w");//重建文件,採用這種方式之前你應該將原文件中的數據都存儲到內存中
操作完畢後應該用fclose(fp);關閉文件,否則會丟失數據
8. 如何用c語言建立哈希表 存有序對
#include<ctype.h>
#include<malloc.h>
#include<limits.h>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define SUCCESS 1
#define UNSUCCESS 0
#define DUPLICATE -1
#define NULLKEY 0 // 0為無記錄標志
#define N 10 // 數據元素個數
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
typedef int Status; // Status是函數的類型,其值是函數結果狀態代碼,如OK等
typedef int Boolean; // Boolean是布爾類型,其值是TRUE或FALSE
typedef int KeyType; // 設關鍵字域為整型
struct ElemType // 數據元素類型
{
KeyType key;
int ord;
};
int hashsize[]={11,19,29,37}; // 哈希表容量遞增表,一個合適的素數序列
int m=0; // 哈希表表長,全局變數
struct HashTable
{
ElemType *elem; // 數據元素存儲基址,動態分配數組
int count; // 當前數據元素個數
int sizeindex; // hashsize[sizeindex]為當前容量
};
Status InitHashTable(HashTable &H)// 操作結果: 構造一個空的哈希表
{ int i;
H.count=0; // 當前元素個數為0
H.sizeindex=0; // 初始存儲容量為hashsize[0]
m=hashsize[0];
H.elem=(ElemType*)malloc(m*sizeof(ElemType));
if(!H.elem)
exit(OVERFLOW); // 存儲分配失敗
for(i=0;i<m;i++)
H.elem[i].key=NULLKEY; // 未填記錄的標志
return OK;
}
void DestroyHashTable(HashTable &H)// 初始條件: 哈希表H存在。操作結果: 銷毀哈希表H
{ free(H.elem);
H.elem=NULL;
H.count=0;
H.sizeindex=0;
}
unsigned Hash(KeyType K)// 一個簡單的哈希函數(m為表長,全局變數)
{ return K%m;
}
void collision(int &p,int d) // 線性探測再散列
{
p=(p+d)%m;// 開放定址法處理沖突
}
Status SearchHash(HashTable H,KeyType K,int &p,int &c)// 在開放定址哈希表H中查找關鍵碼為K的元素,若查找成功,以p指示待查數據
{ p=Hash(K); // 求得哈希地址
while(H.elem[p].key!=NULLKEY&&!EQ(K,H.elem[p].key))
{ // 該位置中填有記錄.並且關鍵字不相等
c++;
if(c<m)
collision(p,c); // 求得下一探查地址p
else
break;
}
if EQ(K,H.elem[p].key)
return SUCCESS; // 查找成功,p返回待查數據元素位置
else
return UNSUCCESS; // 查找不成功(H.elem[p].key==NULLKEY),p返回的是插入位置
}
Status InsertHash(HashTable &,ElemType); // 對函數的聲明
void RecreateHashTable(HashTable &H) // 重建哈希表
{ int i,count=H.count;
ElemType *p,*elem=(ElemType*)malloc(count*sizeof(ElemType));
p=elem;
printf("重建哈希表\n");
for(i=0;i<m;i++) // 保存原有的數據到elem中
if((H.elem+i)->key!=NULLKEY) // 該單元有數據
*p++=*(H.elem+i);
H.count=0;
H.sizeindex++; // 增大存儲容量
m=hashsize[H.sizeindex];
p=(ElemType*)realloc(H.elem,m*sizeof(ElemType));
if(!p)
exit(OVERFLOW); // 存儲分配失敗
H.elem=p;
for(i=0;i<m;i++)
H.elem[i].key=NULLKEY; // 未填記錄的標志(初始化)
for(p=elem;p<elem+count;p++) // 將原有的數據按照新的表長插入到重建的哈希表中
InsertHash(H,*p);
}
Status InsertHash(HashTable &H,ElemType e)// 查找不成功時插入數據元素e到開放定址哈希表H中,並返回OK;
{ int c,p;
c=0;
if(SearchHash(H,e.key,p,c)) // 表中已有與e有相同關鍵字的元素
return DUPLICATE;
else if(c<hashsize[H.sizeindex]/2) // 沖突次數c未達到上限,(c的閥值可調)
{ // 插入e
H.elem[p]=e;
++H.count;
return OK;
}
else
RecreateHashTable(H); // 重建哈希表
return ERROR;
}
void TraverseHash(HashTable H,void(*Vi)(int,ElemType))// 按哈希地址的順序遍歷哈希表
{
printf("哈希地址0~%d\n",m-1);
for(int i=0;i<m;i++)
if(H.elem[i].key!=NULLKEY) // 有數據
Vi(i,H.elem[i]);
}
Status Find(HashTable H,KeyType K,int &p)// 在開放定址哈希表H中查找關鍵碼為K的元素,若查找成功,以p指示待查數據
{ int c=0;
p=Hash(K); // 求得哈希地址
while(H.elem[p].key!=NULLKEY&&!EQ(K,H.elem[p].key))// 該位置中填有記錄.並且關鍵字不相等
{ c++;
if(c<m)
collision(p,c); // 求得下一探查地址p
else
return UNSUCCESS; // 查找不成功(H.elem[p].key==NULLKEY)
}
if EQ(K,H.elem[p].key)
return SUCCESS; // 查找成功,p返回待查數據元素位置
else
return UNSUCCESS; // 查找不成功(H.elem[p].key==NULLKEY)
}
void print(int p,ElemType r)//輸出
{
printf("address=%d (%d,%d)\n",p,r.key,r.ord);
}
void main()
{
ElemType r[N]={{17,1},{60,2},{29,3},{38,4},{1,5},{2,6},{3,7},{4,8},{60,9},{13,10}};
HashTable h;
int i,p;
Status j;
KeyType k;
InitHashTable(h);
for(i=0;i<N-1;i++)// 插入前N-1個記錄
{
j=InsertHash(h,r[i]);
if(j==DUPLICATE)
printf("表中已有關鍵字為%d的記錄,無法再插入記錄(%d,%d)\n",r[i].key,r[i].key,r[i].ord);
}
printf("按哈希地址的順序遍歷哈希表:\n");
TraverseHash(h,print);
printf("請輸入待查找記錄的關鍵字: ");
scanf("%d",&k);
j=Find(h,k,p);
if(j==SUCCESS)
print(p,h.elem[p]);
else
printf("沒找到\n");
j=InsertHash(h,r[i]); // 插入第N個記錄
if(j==ERROR) // 重建哈希表
j=InsertHash(h,r[i]); // 重建哈希表後重新插入
printf("按哈希地址的順序遍歷重建後的哈希表:\n");
TraverseHash(h,print);
printf("請輸入待查找記錄的關鍵字: ");
scanf("%d",&k);
j=Find(h,k,p);
if(j==SUCCESS)
print(p,h.elem[p]);
else
printf("沒找到\n");
DestroyHashTable(h);
}
9. c語言如何讀寫與重建MBR
int biosdisk(int cmd, int drive, int head, int track, int sector, int nsects, void *buffer);
cmd為功能號:
0 重置軟磁碟系統.這強迫驅動器控制器來執行硬復位.忽略所有其它參數.
1 返回最後的硬碟操作狀態.忽略所有其它參數
2 讀磁碟,讀的位置由head、track、sector給出,讀取nsects個扇區到buffer中;
3 寫磁碟。寫的位置是head、track、sector開始的nsects個扇區。要寫的數據在buffer中。
drive為驅動器號(0=A,1=B,0x80=C,0x81=D,0x82=E,依次類推)
head為磁頭 track為磁軌 sector為扇區
nsects為要讀或寫的扇區數
MBR在磁碟的0面0道1扇區,長度為512位元組,所以讀取第1塊硬碟的MBR可以用:
char mbr_buffer[512];
biosdisk(2, 0x80, 0, 0, 1, 1, mbr_buffer);
但是,這不是C語言的標准函數,而是某些編譯器的擴展,本質上是BIOS軟中斷INT13H的介面。所以兼容性受到很大限制,比如正常情況下,在Windows環境中不允許這樣直接訪問硬體的程序運行的,可以在實模式下試試。而且一定要小心,讀還可以,千萬不要輕易寫,一旦出錯就麻煩了。
10. c語言在執行的時候編譯沒有問題,組建的時候錯誤什麼問題
這個沒有問題的。
至少我測試是正常的
你可以重新啟動一下你的 IDE,然後再試試;如果還是不行,將目錄下的一些文件給刪除——保留你的CPP文件,重新編譯試試;如果還是不行,重建一個工程再試試。
如果以上方法都還不行,那才叫有問題了。