1 //对于插入,一般都是现查找再插入,这指的是数据不会相同的情况下 2 /*然后另外一个问题,关于数据的前移问题,,使用的非用for循环一个一个向前移动, 3 而是使用了memcpy进行整体往前拷贝。 4 注意,如果是数据的后移,可以用strcpy,但是前移绝对不能用。 5 6 因为是先查再进行插入,所以在Insert中肯的有一个FindData函数进行查找. 7 8 删除数据时,先找到数据,然后memcpy进行“删除”. 9 */ 10 11 /* 12 本代码为线性表的管理, 13 用到了就是Insert,Delete,Find,Travel等函数 14 */ 15 16 #include<iostream> 17 18 using namespace std; 19 20 #define MAX 3 21 22 23 typedef struct _DATA_ 24 { 25 char szName[20]; 26 char iAge; 27 }Data,*pData; 28 29 30 typedef struct _TABLE_ 31 { 32 int iMax; 33 int iSize; 34 pData pDataTemp; 35 }Table,*pTable; 36 37 bool InsertData(Table& TableTemp, Data DataTemp); 38 39 bool FindData(Data DataTemp,Table& TableTemp); 40 41 bool FindData(Data DataTemp,Table& TableTemp, int& iIndex); 42 43 bool InitTable(Table& TableTemp); 44 45 void DeleteALL(Table& TableTemp); 46 47 void DeleteANode(Data DataTemp,Table& TableTemp); 48 49 void TravelList(Table& TableTemp); 50 51 52 53 int main() 54 { 55 56 Data DataTemp = {0}; 57 Table TableTemp = {0}; 58 InitTable(TableTemp); 59 60 int iIndex = 0; 61 int i = 0; 62 63 int iMethod = 0; 64 65 bool bOK = true; 66 67 while(bOK) 68 { 69 cout<<"1. Insert Data."<<endl; 70 cout<<"2. Delete A Data."<<endl; 71 cout<<"3. Delete AllData."<<endl; 72 cout<<"30. Exit."<<endl; 73 74 cin>>iMethod; 75 76 switch(iMethod) 77 { 78 79 case 1: 80 cout<<"Input name and age:"<<endl; 81 82 cin>>DataTemp.szName 83 >>DataTemp.iAge; 84 InsertData(TableTemp,DataTemp); 85 TravelList(TableTemp); 86 break; 87 case 2: 88 cout<<"Input A Data to Del:"<<endl; 89 90 cin>>DataTemp.szName 91 >>DataTemp.iAge; 92 93 DeleteANode(DataTemp,TableTemp); 94 TravelList(TableTemp); 95 break; 96 case 3: 97 DeleteALL(TableTemp); 98 TravelList(TableTemp); 99 break; 100 case 30: 101 bOK = false; 102 break; 103 } 104 } 105 106 return 0; 107 } 108 109 110 111 void TravelList(Table& TableTemp) 112 { 113 int i = 0; 114 for(i=0;i<TableTemp.iSize;i++) 115 { 116 cout<<TableTemp.pDataTemp[i].szName<<" " 117 <<TableTemp.pDataTemp[i].iAge<<endl; 118 } 119 cout<<endl; 120 } 121 122 123 void DeleteANode(Data DataTemp,Table& TableTemp) 124 { 125 int iIndex = 0; 126 if(!FindData(DataTemp,TableTemp,iIndex)) 127 { 128 return; 129 } 130 //void *memcpy( void *dest, const void *src, size_t count ); 131 132 memcpy(&TableTemp.pDataTemp[iIndex], 133 &TableTemp.pDataTemp[iIndex+1], 134 sizeof(Data)*(TableTemp.iSize-iIndex-1)); 135 136 TableTemp.iSize--; 137 } 138 139 140 void DeleteALL(Table& TableTemp) 141 { 142 if(TableTemp.pDataTemp != NULL) 143 { 144 TableTemp.iMax = 0; 145 TableTemp.iSize = 0; 146 147 delete TableTemp.pDataTemp; 148 } 149 TableTemp.pDataTemp = NULL; 150 } 151 152 153 154 bool InitTable(Table& TableTemp) //初始化 155 { 156 TableTemp.pDataTemp = new Data[MAX]; 157 158 if(TableTemp.pDataTemp != NULL) 159 { 160 TableTemp.iMax = MAX; 161 TableTemp.iSize = 0; 162 163 return true; 164 } 165 166 return false; 167 168 } 169 170 171 bool InsertData(Table& TableTemp, Data DataTemp) //先查再插 172 { 173 if(!FindData(DataTemp,TableTemp)) //如果在线性表中找到这个DataTemp,则返回false,不进行插入. 174 { 175 return false; 176 } 177 178 //插入之前考虑是否要申请内存空间,realloc 函数的使用 179 //void *realloc( void *memblock, size_t size ); 180 //以前分配的内存块的指针,新的大小;由于返回值是空,所以必须强制类型转换 181 182 if(TableTemp.iSize >= TableTemp.iMax) 183 { 184 TableTemp.pDataTemp = (pData)realloc(TableTemp.pDataTemp,sizeof(Data)*TableTemp.iMax*2); 185 TableTemp.iMax *= 2; 186 } 187 //插入数据,然后返回true,结束战斗 188 TableTemp.pDataTemp[TableTemp.iSize] = DataTemp; 189 190 TableTemp.iSize++; 191 192 return true; 193 } 194 195 196 bool FindData(Data DataTemp,Table& TableTemp) 197 { 198 int i = 0; 199 for(i=0;i<TableTemp.iSize;i++) 200 { 201 if(strcmp(TableTemp.pDataTemp[i].szName,DataTemp.szName) == 0 202 && TableTemp.pDataTemp[i].iAge == DataTemp.iAge) 203 return false; //这里是因为如果找到的数据就不再插入,所以是return false. 204 } 205 206 return true; 207 } 208 209 210 211 bool FindData(Data DataTemp,Table& TableTemp,int& iIndex) 212 { 213 int i = 0; 214 for(i=0;i<TableTemp.iSize;i++) 215 { 216 if(strcmp(TableTemp.pDataTemp[i].szName,DataTemp.szName) == 0 217 && TableTemp.pDataTemp[i].iAge == DataTemp.iAge) 218 { 219 iIndex = i; 220 221 return true; //如果找到数据,索引为i,且返回true. 222 } 223 } 224 225 return false; 226 }