数据结构:线性表之链式表实战演练

来源:互联网 发布:输出素数的c语言程序 编辑:程序博客网 时间:2024/06/05 00:53

标题:线性表之链式表实战演练

类别:数据结构

正文: 

一、首先分析在线性表中的两种经典结构:顺序存储结构、链式存储结构。

1、链式存储结构有如下的优点:

(1)由于它并不要求逻辑上相邻的元素在物理位置上也同样相邻,所以它在执行插入、删除以及合并操作时的复杂度将会大大降低。

2、然而它相较于顺序存储结构也存在弱势:

(1)由于顺序存储结构的特点是相邻两元素它们的物理位置也相邻,所以它不需要像链表那样需要额外一个空间用来存储指向逻辑上

相邻位置的地址空间。

(2)同样由于顺序存储结构的物理位置相邻特性,顺序存储结构的随机存取优势明显。

二、根据它们的优劣势来判断它们的使用场景:

1、对于顺序存储结构:

(1)大数据量

(2)无需插入/删除操作

(3)数据存取敏感型项目

(4)表长度确定

2、对于链式存储结构:

(1)数据量不大

(2)需要插入/删除操作

(3)表长度不确定

三、练习实战

1、实战练习背景:

编写一套学生成绩管理系统,要求存储学生的学号(主关键字不可重复)、学生的姓名、学生的成绩(0-100的整数)。

要达到以下功能要求:

(1)往数据表格中添加学生信息

(2)从数据表格中删除学生信息

(3)给数据表格排序

(4)根据关键字查找学生相关信息

2、开发语言及编译环境:

语言:C

IDE : Visual C++ 6.0

3、逻辑流程图:

(1)逻辑分析

在主界面上显示一个菜单,代表五个功能:1.插入节点、2.删除节点、3.对链表按信息排序、4.搜索特定信息的节点、5.退出

(2)流程图


4、代码粗解

(1)数据定义

- 链表节点类型定义 node_t

typedef struct linkNode{  int num;  int score;  char name[16];  struct linkNode* next;} node_t;

- 包含 int 类型变量 num, 代表学生号码

- 包含 int 类型变量 score, 代表学生分数

- 包含 char 类型数组变量 name, 代表学生姓名

- 包含 结构体指针类型变量 next, 代表下个节点地址

- 链式线性表类型定义 linkTable_t

typedef struct linkTable{  node_t* head;  int nodeCount;  sortType_t sortType;} linkTable_t;

- 包含 链式表头节点 head 指针变量

- 包含 int 类型变量 nodeCount, 代表节点数量

- 包含 sortType_t 类型变量 sortType, 代表排序方式


- 链表信息类型定义 tableInfo_t

typedef struct linkInfo{  sortType_t sortType;  int nodeCount;} tableInfo_t;

- 包含 int 类型变量 nodeCount, 代表节点数量

- 包含 sortType_t 类型变量 sortType, 代表排序方式


(2)函数定义

- 初始化链表

- 参数0:需要初始化的链表的地址的地址

- 参数1:需要初始化的链表的链表信息

链表信息中包括:

排序方式:

ASCEND_BY_NUM 代表按照号码升序排列

DESCEND_BY_NUM 代表按照号码降序排列

ASCEND_BY_SCORE 代表按照分数升序排列

DESCEND_BY_SCORE 代表按照分数降序排列

节点数量

- 返回值:初始化链表是否成功

SUCCESS代表成功

FAILED代表失败

- 逻辑:在主函数中声明链表指针变量,具体链表的空间分配由initLink函数来完成,将链表的全部信息初始化(比如节点数量、头节点地址、

以及排序方式)。

/* * * @ function name- initLink  *  * @ brief- To initialize the link table  * * @ date- 2017.5.16 * * @ author- Eric Huang * * @ param- tablink table * *- tabInfolink table initialize informations *- sortType *- ASCEND_BY_NUM *- ASCEND_BY_SCORE *- DESCEND_BY_NUM *- DESCEND_BY_SCORE *- nodeCount * * @ return- bStatus_twhether the operation is success *- SUCCESS *- FAILED * */bStatus_t initLink( linkTable_t** tab, tableInfo_t tabInfo ){  if( NULL == (*tab = (linkTable_t *)malloc(sizeof(linkTable_t))) )  {printf(" Link Table intialize failed !\n");return FAILED;  }  (*tab)->head = NULL;  (*tab)->sortType = tabInfo.sortType;  (*tab)->nodeCount = tabInfo.nodeCount;  return SUCCESS;}

- 插入节点

- 参数0:需要进行操作的链表的地址的地址

- 参数1:需要插入节点的地址

- 返回值:插入节点是否成功

SUCCESS代表成功

FAILED代表失败

- 逻辑:在插入节点过程中,为了减少在排序时的复杂度,所以以用户所选择好的排序方式进行节点的插入。一共四种排序的方式:1.按照

号码升序排列 2.按照号码降序排列 3.按照分数升序排列 4.按照分数降序排列。这样处理的好处是在用户插入节点的时候,链表的顺序就已

经自然而然地排列规整了。

/* * * @ function name- insertNode  *  * @ brief- To insert a node to a link table   * * @ date- 2017.5.16 * * @ author- Eric Huang * * @ param- tablink table * *- newNodenew node * * @ return- bStatus_twhether the operation is success *- SUCCESS *- FAILED * */bStatus_t insertNode( linkTable_t** tab, node_t *newNode ){  node_t *temp, *pTemp;  if( NULL == newNode )  {printf(" node create failed! \n ");return FAILED;  }  else  {// If the link table is emptyif( NULL == (*tab)->head ){  (*tab)->head = newNode;  newNode->next = NULL;  return SUCCESS;}    pTemp = temp = (*tab)->head;(*tab)->nodeCount++;switch( (*tab)->sortType ){case ASCEND_BY_NUM:  while( temp->num <= newNode->num && temp->next != NULL )  { pTemp = temp;temp = temp->next;  }  if( temp->num >= newNode->num )  {if( (*tab)->head == temp ){  (*tab)->head = newNode;  newNode->next = temp;}else{  pTemp->next = newNode;  newNode->next = temp;}  }  else  {temp->next = newNode;newNode->next = NULL;  }  break;case ASCEND_BY_SCORE:  while( temp->score <= newNode->score && temp->next != NULL )  {pTemp = temp;temp = temp->next;  }  if( temp->score >= newNode->score )  {if( (*tab)->head == temp ){  (*tab)->head = newNode;  newNode->next = temp;}else{  pTemp->next = newNode;  newNode->next = temp;}  }  else  {temp->next = newNode;newNode->next = NULL;  }  break;case DESCEND_BY_NUM:  while( temp->num >= newNode->num && temp->next != NULL )  {    pTemp = temp;    temp = temp->next;  }  if( temp->num <= newNode->num )  {if( (*tab)->head == temp ){  (*tab)->head = newNode;  newNode->next = temp;}else{  pTemp->next = newNode;  newNode->next = temp;}  }  else  {temp->next = newNode;newNode->next = NULL;  }  break;case DESCEND_BY_SCORE:  while( temp->score >= newNode->score && temp->next != NULL )  {pTemp = temp;temp = temp->next;  }  if( temp->score <= newNode->score )  {if( (*tab)->head == temp ){  (*tab)->head = newNode;  newNode->next = temp;}else{  pTemp->next = newNode;  newNode->next = temp;}  }  else  {temp->next = newNode;newNode->next = NULL;  }default:  // Should never get here!  break;}return SUCCESS;  }}

- 删除节点

- 参数0:需要进行操作的链表的地址的地址

- 参数1:查询方式

FIND_BY_NUM 根据号码删除

FIND_BY_NAME 根据姓名删除

- 参数2:数据

可能为整形,可能为字符串,根据参数1来强制类型转换

- 返回值:删除节点是否成功

SUCCESS代表成功

FAILED代表失败

- 逻辑:根据用户的需求对用户所挑选的节点进行删除操作,当用户发现需要删除的节点在链表中有重复,则将重复的节点信息全部反馈给

用户,并由用户挑选到底要删除哪一个节点。

/* * * @ function name- deleteNode  *  * @ brief- To delete a node from a table  * * @ date- 2017.5.16 * * @ author- Eric Huang * * @ param- tablink table * *- findTypedelete by *- FIND_BY_NUM *- FIND_BY_NAME * *- datathe data for query * * @ return- bStatus_twhether the operation is success *- SUCCESS *- FAILED * */bStatus_t deleteNode( linkTable_t** tab, findType_t findType, void *data ){  int *num;  char* name;  node_t *temp, *pTemp;  temp = (*tab)->head;  switch(findType)  {  case FIND_BY_NUMBER:num = (int *)(data);while( NULL != temp->next ){  if(temp->num == *num)  {    break;  }  pTemp = temp;  temp = temp->next;}if(temp == (*tab)->head){  (*tab)->head = (*tab)->head->next;  pTemp = temp;}if( NULL == temp->next ){  printf(" the number is not exist ! \n ");  return FAILED;}else{  pTemp->next = temp->next;  free(temp);}(void)name;break;  case FIND_BY_NAME:name = (char *)(data);while( NULL != temp->next ){  if( !strcmp(name, temp->name) )  {    break;  }  pTemp = temp;  temp = temp->next;}if(temp == (*tab)->head){  (*tab)->head = (*tab)->head->next;  pTemp = temp;}if( NULL == temp->next ){  printf(" the number is not exist ! \n ");  return FAILED;}else{  pTemp->next = temp->next;  free(temp);}    (void)num;break;  default:break;  }  (*tab)->nodeCount--;  return SUCCESS;}

- 插入节点逻辑实现

- 参数0:需要进行操作的链表的地址的地址

- 参数1:需要插入节点的地址

- 返回值:插入节点是否成功

SUCCESS代表成功

FAILED代表失败

- 逻辑:在插入节点过程中,不在insertNode函数里对新节点进行内存的空间分配而在上层插入节点逻辑实现函数中分配内存空间,这样做的

好处是,底层的insertNode函数还可以继续在其它函数中进行复用。

/* * * @ function name- insertFunction *  * @ brief- For insertion process   * * @ date- 2017.5.16 * * @ author- Eric Huang * * @ param- tablink table * *- newNodethe new node ready for insertion * * @ return- bStatus_twhether the operation is success *- SUCCESS *- FAILED * */bStatus_t insertFunction( linkTable_t** tab, node_t *newNode ){  newNode = (node_t *)malloc(sizeof(node_t));  if( FAILED == getNodeInfo( tab, newNode ) )  {printf(" node create failed !\n ");return FAILED;  }  if( FAILED == insertNode( tab, newNode ) )  {    printf(" node insert failed ! \n ");return FAILED;  }  printf(" node insert successfully ! \n");  return SUCCESS;}

- 链表排序

- 参数0:需要进行操作的链表的地址的地址

- 返回值:链表排序是否成功

SUCCESS代表成功

FAILED代表失败

- 逻辑:根据链表的排序方式对链表进行排序,在这里,我的思路是将原节点遍历一一调出并将它们按照新的顺序一一插入到新的链式表中

并将新的链式表返回。

/* * * @ function name- linkSort  *  * @ brief- Sequencing the link table * * @ date- 2017.5.16 * * @ author- Eric Huang * * @ param- tablink table * * @ return- bStatus_twhether the operation is success *- SUCCESS *- FAILED * */bStatus_t linkSort( linkTable_t** tab ){  linkTable_t *tabTemp, *freeTemp;  node_t *temp, *pTemp;  tableInfo_t tabInfo =   {(*tab)->sortType,    0,  };  if( NULL == (*tab)->head )return FAILED;  if( FAILED == initLink( &tabTemp, tabInfo ) )  {    return FAILED;  }  pTemp = temp = (*tab)->head;  while( NULL != temp )  {pTemp = pTemp->next;insertNode( &tabTemp, temp );temp = pTemp;  }  freeTemp = (*tab);  (*tab) = tabTemp;    free(freeTemp);  return SUCCESS;}

- 打印链表

- 参数0:需要进行操作的链表的地址的地址

- 返回值:无

- 逻辑:遍历链式表并将链式表中的节点打印出来

/* * * @ function name- linkPrint  *  * @ brief- For printout the link table * * @ date- 2017.5.16 * * @ author- Eric Huang * * @ param- tablink table * * @ return- none * */void linkPrint( linkTable_t **tab ){  node_t *temp;  temp = (*tab)->head;  if( NULL == temp )  {    printf(" you can not print an empty table ! \n");return;  }  printf(" \n ------------------------------------ \n");  printf("    the total count of nodes is : %d \n", (*tab)->nodeCount + 1);  printf(" ------------------------------------ \n");  printf(" NUMBER:    NAME:    SCORE: \n");  while( NULL != temp )  {    printf("%8d %8s %8d \n", temp->num, temp->name, temp->score);temp = temp->next;  }}

- 查找某特定节点

- 参数0:需要进行操作的链表的地址的地址

- 参数1:查找方式

FIND_BY_NUMBER 根据号码查找

FIND_BY_NAME 根据姓名查找

FIND_BY_SCORE 根据分数查找

- 返回值:无

- 逻辑:遍历链式表并将符合条件的链式表中的节点打印出来

/* * * @ function name- printSelected  *  * @ brief- For printout the selected elements in link table * * @ date- 2017.5.16 * * @ author- Eric Huang * * @ param- tablink table * *- findTypequery method *- FIND_BY_NUMBER *- FIND_BY_NAME *- FIND_BY_SCORE * *- data * * @ return- none * */void printSelected( linkTable_t **tab, findType_t findType, void *data ){  int *num;  char* name;  node_t *temp;  temp = (*tab)->head;  if( NULL == temp )  {    printf(" you can not print an empty table ! \n");return;  }  printf(" \n ------------------------------------ \n");  printf("     The selected nodes are:\n");  printf(" ------------------------------------ \n");  printf(" NUMBER:    NAME:    SCORE: \n");  if( FIND_BY_NUMBER == findType || FIND_BY_SCORE == findType )  {    num = (int *)data;while( NULL != temp ){  if( FIND_BY_NUMBER == findType )  {    if( *num == temp->num ){    printf("%8d %8s %8d \n", temp->num, temp->name, temp->score);}  }  else  {    if( *num == temp->score ){    printf("%8d %8s %8d \n", temp->num, temp->name, temp->score);}  }  temp = temp->next;}(void)name;  }  else  {    name = (char *)data;while( NULL != temp ){  if( !strcmp(name, temp->name) )  {printf("%8d %8s %8d \n", temp->num, temp->name, temp->score);  }  temp = temp->next;}(void)num;  }}

- 获取用户主菜单输入信息

/* * * @ function name- getOperation  *  * @ brief- get the current user operation * * @ date- 2017.5.16 * * @ author- Eric Huang * * @ param- none * * @ return- operationType_twhich operation does user choose *- INSERTNODE *- DELETENODE *- SEQUENCING *- SELECT *- SHOWTAB *- EXIT * */operationType_t getOperation(){  operationType_t ops;  scanf("%d", &ops);  return ops > 4 ? 5 : ops;}

- 得到链表内重名学生的个数
/* * * @ function name- getSameNameCount  *  * @ brief- get the duplicated nodes by same name * * @ date- 2017.5.16 * * @ author- Eric Huang * * @ param- tabthe link table * *- namethe name * * @ return- intthe count of the duplicated nodes * */int getSameNameCount( linkTable_t** tab, char *name ){  int count = 0;  node_t* temp;  temp = (*tab)->head;  if(NULL == temp)return 0;  while(NULL != temp)  {    if( !strcmp(temp->name, name) )  count++;temp = temp->next;  }  return count;}

- 判断节点是否存在
static existStatus_t getNodeExistStatus( linkTable_t** tab, int num ){  existStatus_t status = NOTEXIST;  node_t* temp;  temp = (*tab)->head;  if(NULL == temp)return NOTEXIST;  while(NULL != temp)  {    if( temp->num == num )  return EXIST;temp = temp->next;  }  return NOTEXIST;}

- 从用户输入得到节点信息
static bStatus_t getNodeInfo( linkTable_t **tab, node_t* newNode ){  // Input the information  if( NULL == newNode )return FAILED;  else  {printf(" please input the information of the node that you'd insert! \n");printf(" the node number(greater than 0): ");scanf("%d", &(newNode->num));while(newNode->num < 1 || (EXIST == getNodeExistStatus( tab, newNode->num )) ){  printf(" your input data is invalid, please retry! \n the node number(greater than 0): ");  scanf("%d", &(newNode->num));  } printf(" the node name: ");scanf("%s", newNode->name);while(newNode->name == NULL){  printf(" your input data is invalid, please retry! \n the node name: ");  scanf("%d", newNode->name);  }printf(" the node score(greater than 0 and less than 100): ");scanf("%d", &(newNode->score));while(newNode->score < SCORE_MIN || newNode->score > SCORE_MAX){  printf(" your input data is invalid, please retry! \n the node score(greater than 0 and less than 100): ");  scanf("%d", &(newNode->score));}return SUCCESS;  }}

- 主函数
/*====== * MAIN =======*/int main( int argc, char** argv ){  /* Setup */  linkTable_t* myTable;  node_t* newNode = NULL;  findType_t findType = FIND_BY_NUMBER;  tableInfo_t defaultInfo =   {    ASCEND_BY_NUM,0,  };  static char queryName[16];  int queryNum = 0;  char command = 0;  int count = 0;  operationType_t myOperation;  if( FAILED == initLink( &myTable, defaultInfo ) )  {printf(" link table did not create successfully !\n");return 0;  }    /* Loop */  while(1)  {HINT();myOperation = getOperation();/* Excution */switch(myOperation){case INSERTNODE:  while(1)  {    insertFunction( &myTable, newNode );linkPrint( &myTable );printf(" continue to insert the node ? (y/n) \n");getchar();command = getchar();if( command == 'N' || command == 'n' )  break;  }  break;case DELETENODE:  while(1)  {if( NULL == myTable->head ){      printf(" Can not operate ! Please at least insert one node into the list fisrt ! \n");  break;}else{  linkPrint( &myTable );  printf(" Which way would u like to delete your specific node ? \n");  printf(" 0.BY NUMBER \n");  printf(" 1.BY NAME \n");  printf(" 2.CANCEL \n");  getchar();  command = getchar();  if( command == '0' )  {    printf(" Please input the node number u'd delete : \n");scanf("%d", &queryNum);deleteNode( &myTable, FIND_BY_NUMBER, &queryNum );    linkPrint( &myTable );  }  else if( command == '1' )  {    printf(" Please input the node name u'd delete : \n");scanf("%s", queryName);    count = getSameNameCount( &myTable, queryName );if( count == 0 ){  printf(" There is no such node in the link table ! \n");      linkPrint( &myTable );}else if( count == 1 ){  deleteNode( &myTable, FIND_BY_NAME, queryName );  linkPrint( &myTable );}else{  printSelected( &myTable, FIND_BY_NAME, queryName );  printf(" There is duplicated nodes in the table , Please select the specific node by node number : \n");  scanf("%d", &queryNum);    deleteNode( &myTable, FIND_BY_NUMBER, &queryNum );      linkPrint( &myTable );}  }  else  {    break;  }  printf(" continue to delete the node ? (y/n) \n");  getchar();  command = getchar();  if( command == 'N' || command == 'n' )    break;}  }  break;case SEQUENCING:  while(1)  {    if( NULL == myTable->head ){      printf(" Can not operate ! Please at least insert one node into the list fisrt ! \n");  break;}else{  linkPrint( &myTable );  printf(" Which way would u like to sort ur table ? \n");  printf(" 0.ASCEND BY NUMBER \n");  printf(" 1.ASCEND BY SCORE \n");  printf(" 2.DESCEND BY NUMBER \n");  printf(" 3.DESCEND BY SCORE \n");  printf(" 4.CANCEL \n");  getchar();  command = getchar();  if(command == '0')  {    myTable->sortType = ASCEND_BY_NUM;linkSort( &myTable );    linkPrint( &myTable );  }  else if(command == '1')  {    myTable->sortType = ASCEND_BY_SCORE;linkSort( &myTable );    linkPrint( &myTable );  }  else if(command == '2')  {    myTable->sortType = DESCEND_BY_NUM;linkSort( &myTable );    linkPrint( &myTable );  }  else if(command == '3')  {    myTable->sortType = DESCEND_BY_SCORE;linkSort( &myTable );    linkPrint( &myTable );  }  else  {    break;  }  printf(" continue to sequencing ? (y/n) \n");  getchar();  command = getchar();  if( command == 'N' || command == 'n' )    break;}  }  break;case SELECT:  while(1)  {    if( NULL == myTable->head ){      printf(" Can not operate ! Please at least insert one node into the list fisrt ! \n");  break;}else{  linkPrint( &myTable );  printf(" Which way would u like to find your specific data ? \n");  printf(" 0.FIND BY NUMBER \n");  printf(" 1.FIND BY NAME \n");  printf(" 2.FIND BY SCORE \n");  printf(" 3.CANCEL \n");  getchar();  command = getchar();  if( command == '0' )  {    printf(" Please input the number u'd search :\n");scanf("%d", &queryNum);printSelected( &myTable, FIND_BY_NUMBER, &queryNum );break;  }  else if( command == '1' )  {    printf(" Please input the name u'd search :\n");scanf("%s", queryName);printSelected( &myTable, FIND_BY_NAME, queryName );break;  }  else if( command == '2' )  {    printf(" Please input the score u'd search :\n");scanf("%d", &queryNum);printSelected( &myTable, FIND_BY_SCORE, &queryNum );break;  }  else  {    break;  }}  }  break;case SHOWTAB:  linkPrint( &myTable );  break;case EXIT:  return 0;  break;default:  // Should never get here !  break;}  }  return 0;}

5、写在最后

代码中应该还有缺陷,也希望各位朋友能够指出,一下为代码源码及VC6.0下的调试结果:





源码:

/*============================== * * name- exercise1  *  * projectname- 链式表例子   * * date- 2017.5.16 * * author- Eric Huang * ===============================*//*========== * INCLUDES ===========*/#include "stdio.h"#include "stdlib.h"#include "string.h"/*======== * MACROS =========*/#define SCORE_MAX100#define SCORE_MIN0#define HINT()do\{\  printf(" Please select your operation : \n");\  printf(" 0 - Insert a node to the current link table\n");\  printf(" 1 - Delete a node from the link table \n");\  printf(" 2 - Sequencing the link table \n");\  printf(" 3 - Select the specific nodes \n");\  printf(" 4 - Show the link table \n");\  printf(" 5 - Exit \n");\} while(0)\/*================ * GLOBAL VARIBLES =================*//*=========== * ENUM TYPES ============*/typedef enum b_status{  SUCCESS,  FAILED,} bStatus_t;typedef enum exist_status{  EXIST,  NOTEXIST,} existStatus_t;typedef enum sort_type{  ASCEND_BY_NUM,  ASCEND_BY_SCORE,  DESCEND_BY_NUM,  DESCEND_BY_SCORE,} sortType_t;typedef enum find_type{  FIND_BY_NUMBER,  FIND_BY_NAME,  FIND_BY_SCORE,} findType_t;typedef enum operation_type{  INSERTNODE,  DELETENODE,  SEQUENCING,  SELECT,  SHOWTAB,  EXIT,} operationType_t;/*============= * TYPE DEFINES ==============*/typedef struct linkNode{  int num;  int score;  char name[16];  struct linkNode* next;} node_t;typedef struct linkTable{  node_t* head;  int nodeCount;  sortType_t sortType;} linkTable_t;typedef struct linkInfo{  sortType_t sortType;  int nodeCount;} tableInfo_t;/*================ * FUNCTION DECLARATION =================*/int getSameNameCount( linkTable_t** tab, char *name );void printSelected( linkTable_t **tab, findType_t findType, void *data );void linkPrint( linkTable_t **tab );operationType_t getOperation();bStatus_t linkSort( linkTable_t** tab );bStatus_t insertFunction( linkTable_t** tab, node_t *newNode );bStatus_t deleteNode( linkTable_t** tab, findType_t findType, void *data );bStatus_t insertNode( linkTable_t** tab, node_t *newNode );bStatus_t initLink( linkTable_t** tab, tableInfo_t tabInfo );/*=================== * INTERNAL FUNCTIONS ====================*/static existStatus_t getNodeExistStatus( linkTable_t** tab, int num ){  existStatus_t status = NOTEXIST;  node_t* temp;  temp = (*tab)->head;  if(NULL == temp)return NOTEXIST;  while(NULL != temp)  {    if( temp->num == num )  return EXIST;temp = temp->next;  }  return NOTEXIST;}static bStatus_t getNodeInfo( linkTable_t **tab, node_t* newNode ){  // Input the information  if( NULL == newNode )return FAILED;  else  {printf(" please input the information of the node that you'd insert! \n");printf(" the node number(greater than 0): ");scanf("%d", &(newNode->num));while(newNode->num < 1 || (EXIST == getNodeExistStatus( tab, newNode->num )) ){  printf(" your input data is invalid, please retry! \n the node number(greater than 0): ");  scanf("%d", &(newNode->num));  } printf(" the node name: ");scanf("%s", newNode->name);while(newNode->name == NULL){  printf(" your input data is invalid, please retry! \n the node name: ");  scanf("%d", newNode->name);  }printf(" the node score(greater than 0 and less than 100): ");scanf("%d", &(newNode->score));while(newNode->score < SCORE_MIN || newNode->score > SCORE_MAX){  printf(" your input data is invalid, please retry! \n the node score(greater than 0 and less than 100): ");  scanf("%d", &(newNode->score));}return SUCCESS;  }}/*================= * GLOBAL FUNCTIONS ==================*//* * * @ function name- initLink  *  * @ brief- To initialize the link table  * * @ date- 2017.5.16 * * @ author- Eric Huang * * @ param- tablink table * *- tabInfolink table initialize informations *- sortType *- ASCEND_BY_NUM *- ASCEND_BY_SCORE *- DESCEND_BY_NUM *- DESCEND_BY_SCORE *- nodeCount * * @ return- bStatus_twhether the operation is success *- SUCCESS *- FAILED * */bStatus_t initLink( linkTable_t** tab, tableInfo_t tabInfo ){  if( NULL == (*tab = (linkTable_t *)malloc(sizeof(linkTable_t))) )  {printf(" Link Table intialize failed !\n");return FAILED;  }  (*tab)->head = NULL;  (*tab)->sortType = tabInfo.sortType;  (*tab)->nodeCount = tabInfo.nodeCount;  return SUCCESS;}/* * * @ function name- insertNode  *  * @ brief- To insert a node to a link table   * * @ date- 2017.5.16 * * @ author- Eric Huang * * @ param- tablink table * *- newNodenew node * * @ return- bStatus_twhether the operation is success *- SUCCESS *- FAILED * */bStatus_t insertNode( linkTable_t** tab, node_t *newNode ){  node_t *temp, *pTemp;  if( NULL == newNode )  {printf(" node create failed! \n ");return FAILED;  }  else  {// If the link table is emptyif( NULL == (*tab)->head ){  (*tab)->head = newNode;  newNode->next = NULL;  return SUCCESS;}    pTemp = temp = (*tab)->head;(*tab)->nodeCount++;switch( (*tab)->sortType ){case ASCEND_BY_NUM:  while( temp->num <= newNode->num && temp->next != NULL )  { pTemp = temp;temp = temp->next;  }  if( temp->num >= newNode->num )  {if( (*tab)->head == temp ){  (*tab)->head = newNode;  newNode->next = temp;}else{  pTemp->next = newNode;  newNode->next = temp;}  }  else  {temp->next = newNode;newNode->next = NULL;  }  break;case ASCEND_BY_SCORE:  while( temp->score <= newNode->score && temp->next != NULL )  {pTemp = temp;temp = temp->next;  }  if( temp->score >= newNode->score )  {if( (*tab)->head == temp ){  (*tab)->head = newNode;  newNode->next = temp;}else{  pTemp->next = newNode;  newNode->next = temp;}  }  else  {temp->next = newNode;newNode->next = NULL;  }  break;case DESCEND_BY_NUM:  while( temp->num >= newNode->num && temp->next != NULL )  {    pTemp = temp;    temp = temp->next;  }  if( temp->num <= newNode->num )  {if( (*tab)->head == temp ){  (*tab)->head = newNode;  newNode->next = temp;}else{  pTemp->next = newNode;  newNode->next = temp;}  }  else  {temp->next = newNode;newNode->next = NULL;  }  break;case DESCEND_BY_SCORE:  while( temp->score >= newNode->score && temp->next != NULL )  {pTemp = temp;temp = temp->next;  }  if( temp->score <= newNode->score )  {if( (*tab)->head == temp ){  (*tab)->head = newNode;  newNode->next = temp;}else{  pTemp->next = newNode;  newNode->next = temp;}  }  else  {temp->next = newNode;newNode->next = NULL;  }default:  // Should never get here!  break;}return SUCCESS;  }}/* * * @ function name- deleteNode  *  * @ brief- To delete a node from a table  * * @ date- 2017.5.16 * * @ author- Eric Huang * * @ param- tablink table * *- findTypedelete by *- FIND_BY_NUM *- FIND_BY_NAME * *- datathe data for query * * @ return- bStatus_twhether the operation is success *- SUCCESS *- FAILED * */bStatus_t deleteNode( linkTable_t** tab, findType_t findType, void *data ){  int *num;  char* name;  node_t *temp, *pTemp;  temp = (*tab)->head;  switch(findType)  {  case FIND_BY_NUMBER:num = (int *)(data);while( NULL != temp->next ){  if(temp->num == *num)  {    break;  }  pTemp = temp;  temp = temp->next;}if(temp == (*tab)->head){  (*tab)->head = (*tab)->head->next;  pTemp = temp;}if( NULL == temp->next ){  printf(" the number is not exist ! \n ");  return FAILED;}else{  pTemp->next = temp->next;  free(temp);}(void)name;break;  case FIND_BY_NAME:name = (char *)(data);while( NULL != temp->next ){  if( !strcmp(name, temp->name) )  {    break;  }  pTemp = temp;  temp = temp->next;}if(temp == (*tab)->head){  (*tab)->head = (*tab)->head->next;  pTemp = temp;}if( NULL == temp->next ){  printf(" the number is not exist ! \n ");  return FAILED;}else{  pTemp->next = temp->next;  free(temp);}    (void)num;break;  default:break;  }  (*tab)->nodeCount--;  return SUCCESS;}/* * * @ function name- insertFunction *  * @ brief- For insertion process   * * @ date- 2017.5.16 * * @ author- Eric Huang * * @ param- tablink table * *- newNodethe new node ready for insertion * * @ return- bStatus_twhether the operation is success *- SUCCESS *- FAILED * */bStatus_t insertFunction( linkTable_t** tab, node_t *newNode ){  newNode = (node_t *)malloc(sizeof(node_t));  if( FAILED == getNodeInfo( tab, newNode ) )  {printf(" node create failed !\n ");return FAILED;  }  if( FAILED == insertNode( tab, newNode ) )  {    printf(" node insert failed ! \n ");return FAILED;  }  printf(" node insert successfully ! \n");  return SUCCESS;}/* * * @ function name- linkSort  *  * @ brief- Sequencing the link table * * @ date- 2017.5.16 * * @ author- Eric Huang * * @ param- tablink table * * @ return- bStatus_twhether the operation is success *- SUCCESS *- FAILED * */bStatus_t linkSort( linkTable_t** tab ){  linkTable_t *tabTemp, *freeTemp;  node_t *temp, *pTemp;  tableInfo_t tabInfo =   {(*tab)->sortType,    0,  };  if( NULL == (*tab)->head )return FAILED;  if( FAILED == initLink( &tabTemp, tabInfo ) )  {    return FAILED;  }  pTemp = temp = (*tab)->head;  while( NULL != temp )  {pTemp = pTemp->next;insertNode( &tabTemp, temp );temp = pTemp;  }  freeTemp = (*tab);  (*tab) = tabTemp;    free(freeTemp);  return SUCCESS;}/* * * @ function name- linkPrint  *  * @ brief- For printout the link table * * @ date- 2017.5.16 * * @ author- Eric Huang * * @ param- tablink table * * @ return- none * */void linkPrint( linkTable_t **tab ){  node_t *temp;  temp = (*tab)->head;  if( NULL == temp )  {    printf(" you can not print an empty table ! \n");return;  }  printf(" \n ------------------------------------ \n");  printf("    the total count of nodes is : %d \n", (*tab)->nodeCount + 1);  printf(" ------------------------------------ \n");  printf(" NUMBER:    NAME:    SCORE: \n");  while( NULL != temp )  {    printf("%8d %8s %8d \n", temp->num, temp->name, temp->score);temp = temp->next;  }}/* * * @ function name- printSelected  *  * @ brief- For printout the selected elements in link table * * @ date- 2017.5.16 * * @ author- Eric Huang * * @ param- tablink table * *- findTypequery method *- FIND_BY_NUMBER *- FIND_BY_NAME *- FIND_BY_SCORE * *- data * * @ return- none * */void printSelected( linkTable_t **tab, findType_t findType, void *data ){  int *num;  char* name;  node_t *temp;  temp = (*tab)->head;  if( NULL == temp )  {    printf(" you can not print an empty table ! \n");return;  }  printf(" \n ------------------------------------ \n");  printf("     The selected nodes are:\n");  printf(" ------------------------------------ \n");  printf(" NUMBER:    NAME:    SCORE: \n");  if( FIND_BY_NUMBER == findType || FIND_BY_SCORE == findType )  {    num = (int *)data;while( NULL != temp ){  if( FIND_BY_NUMBER == findType )  {    if( *num == temp->num ){    printf("%8d %8s %8d \n", temp->num, temp->name, temp->score);}  }  else  {    if( *num == temp->score ){    printf("%8d %8s %8d \n", temp->num, temp->name, temp->score);}  }  temp = temp->next;}(void)name;  }  else  {    name = (char *)data;while( NULL != temp ){  if( !strcmp(name, temp->name) )  {printf("%8d %8s %8d \n", temp->num, temp->name, temp->score);  }  temp = temp->next;}(void)num;  }}/* * * @ function name- getOperation  *  * @ brief- get the current user operation * * @ date- 2017.5.16 * * @ author- Eric Huang * * @ param- none * * @ return- operationType_twhich operation does user choose *- INSERTNODE *- DELETENODE *- SEQUENCING *- SELECT *- SHOWTAB *- EXIT * */operationType_t getOperation(){  operationType_t ops;  scanf("%d", &ops);  return ops > 4 ? 5 : ops;}/* * * @ function name- getSameNameCount  *  * @ brief- get the duplicated nodes by same name * * @ date- 2017.5.16 * * @ author- Eric Huang * * @ param- tabthe link table * *- namethe name * * @ return- intthe count of the duplicated nodes * */int getSameNameCount( linkTable_t** tab, char *name ){  int count = 0;  node_t* temp;  temp = (*tab)->head;  if(NULL == temp)return 0;  while(NULL != temp)  {    if( !strcmp(temp->name, name) )  count++;temp = temp->next;  }  return count;}/*====== * MAIN =======*/int main( int argc, char** argv ){  /* Setup */  linkTable_t* myTable;  node_t* newNode = NULL;  findType_t findType = FIND_BY_NUMBER;  tableInfo_t defaultInfo =   {    ASCEND_BY_NUM,0,  };  static char queryName[16];  int queryNum = 0;  char command = 0;  int count = 0;  operationType_t myOperation;  if( FAILED == initLink( &myTable, defaultInfo ) )  {printf(" link table did not create successfully !\n");return 0;  }    /* Loop */  while(1)  {HINT();myOperation = getOperation();/* Excution */switch(myOperation){case INSERTNODE:  while(1)  {    insertFunction( &myTable, newNode );linkPrint( &myTable );printf(" continue to insert the node ? (y/n) \n");getchar();command = getchar();if( command == 'N' || command == 'n' )  break;  }  break;case DELETENODE:  while(1)  {if( NULL == myTable->head ){      printf(" Can not operate ! Please at least insert one node into the list fisrt ! \n");  break;}else{  linkPrint( &myTable );  printf(" Which way would u like to delete your specific node ? \n");  printf(" 0.BY NUMBER \n");  printf(" 1.BY NAME \n");  printf(" 2.CANCEL \n");  getchar();  command = getchar();  if( command == '0' )  {    printf(" Please input the node number u'd delete : \n");scanf("%d", &queryNum);deleteNode( &myTable, FIND_BY_NUMBER, &queryNum );    linkPrint( &myTable );  }  else if( command == '1' )  {    printf(" Please input the node name u'd delete : \n");scanf("%s", queryName);    count = getSameNameCount( &myTable, queryName );if( count == 0 ){  printf(" There is no such node in the link table ! \n");      linkPrint( &myTable );}else if( count == 1 ){  deleteNode( &myTable, FIND_BY_NAME, queryName );  linkPrint( &myTable );}else{  printSelected( &myTable, FIND_BY_NAME, queryName );  printf(" There is duplicated nodes in the table , Please select the specific node by node number : \n");  scanf("%d", &queryNum);    deleteNode( &myTable, FIND_BY_NUMBER, &queryNum );      linkPrint( &myTable );}  }  else  {    break;  }  printf(" continue to delete the node ? (y/n) \n");  getchar();  command = getchar();  if( command == 'N' || command == 'n' )    break;}  }  break;case SEQUENCING:  while(1)  {    if( NULL == myTable->head ){      printf(" Can not operate ! Please at least insert one node into the list fisrt ! \n");  break;}else{  linkPrint( &myTable );  printf(" Which way would u like to sort ur table ? \n");  printf(" 0.ASCEND BY NUMBER \n");  printf(" 1.ASCEND BY SCORE \n");  printf(" 2.DESCEND BY NUMBER \n");  printf(" 3.DESCEND BY SCORE \n");  printf(" 4.CANCEL \n");  getchar();  command = getchar();  if(command == '0')  {    myTable->sortType = ASCEND_BY_NUM;linkSort( &myTable );    linkPrint( &myTable );  }  else if(command == '1')  {    myTable->sortType = ASCEND_BY_SCORE;linkSort( &myTable );    linkPrint( &myTable );  }  else if(command == '2')  {    myTable->sortType = DESCEND_BY_NUM;linkSort( &myTable );    linkPrint( &myTable );  }  else if(command == '3')  {    myTable->sortType = DESCEND_BY_SCORE;linkSort( &myTable );    linkPrint( &myTable );  }  else  {    break;  }  printf(" continue to sequencing ? (y/n) \n");  getchar();  command = getchar();  if( command == 'N' || command == 'n' )    break;}  }  break;case SELECT:  while(1)  {    if( NULL == myTable->head ){      printf(" Can not operate ! Please at least insert one node into the list fisrt ! \n");  break;}else{  linkPrint( &myTable );  printf(" Which way would u like to find your specific data ? \n");  printf(" 0.FIND BY NUMBER \n");  printf(" 1.FIND BY NAME \n");  printf(" 2.FIND BY SCORE \n");  printf(" 3.CANCEL \n");  getchar();  command = getchar();  if( command == '0' )  {    printf(" Please input the number u'd search :\n");scanf("%d", &queryNum);printSelected( &myTable, FIND_BY_NUMBER, &queryNum );break;  }  else if( command == '1' )  {    printf(" Please input the name u'd search :\n");scanf("%s", queryName);printSelected( &myTable, FIND_BY_NAME, queryName );break;  }  else if( command == '2' )  {    printf(" Please input the score u'd search :\n");scanf("%d", &queryNum);printSelected( &myTable, FIND_BY_SCORE, &queryNum );break;  }  else  {    break;  }}  }  break;case SHOWTAB:  linkPrint( &myTable );  break;case EXIT:  return 0;  break;default:  // Should never get here !  break;}  }  return 0;}


原创粉丝点击