思路是把一个大的链表按照字母分为26个小表,每个小链表中的单词都以同一个字母开头。
下面是实现的程序,核心步骤都有注释。
转载请注明出处:http://www.cnblogs.com/zydark/p/8891386.html
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <ctype.h> 5 #include <assert.h> 6 #define N 30 7 typedef struct WORD{//保存由value开头的所有单词,由不同字母开头的单词 8 struct WORD *next; 9 char *word; 10 } Word; 11 12 13 typedef struct NODE{//保存所有的单词 14 struct NODE *next; 15 char letter; 16 Word* data; 17 } Node; 18 int insert(Node **rootp,char *str); 19 void print(Node* rootp); 20 int main (void) 21 { 22 Node* p1=(Node*)malloc(sizeof(Node)); 23 if(p1==NULL) 24 perror("malloc error"); 25 26 p1->next=NULL; 27 p1->letter='a'; 28 Word* the_word; 29 the_word=(Word*)malloc(sizeof(Word)); 30 if(the_word==NULL) 31 perror("malloc error"); 32 33 the_word->next=NULL; 34 35 the_word->word=(char*)malloc(N); 36 if(the_word->word=NULL) 37 perror("malloc error"); 38 39 the_word->word="ahello"; 40 41 p1->data=the_word; 42 43 char value[N]; 44 printf("输入插入的字符串:\n"); 45 while(fgets(value,N,stdin)!=NULL) 46 { 47 value[strlen(value)-1]='\0';//处理fgets读入的换行符转为结束符 48 insert(&p1,value); 49 } 50 51 52 print(p1); 53 54 } 55 int insert(Node **rootp,char *the_word) 56 { 57 Node* current_node; 58 Word* current_word; 59 Word** wordlink; 60 int first_letter; 61 Word* new_word; 62 Node* new_node; 63 int num; 64 65 first_letter=*the_word;//获取插入字符串的首字符 66 if(isalpha(first_letter)==0) //如果首字符不是字母,出错返回 67 return -1; 68 69 while((current_node=*rootp)!=NULL&¤t_node->letter<first_letter) 70 rootp=¤t_node->next; 71 72 /*如果current_node==NULL或者当前节点中的letter大于等于first_letter跳出循环*/ 73 if(current_node==NULL||current_node->letter>first_letter) 74 /*如果当前节点为NULL,或者当前节点的字符索引大于first_letter 75 创建一个新的节点并插入到索引表中*/ 76 { 77 new_node=(Node*)malloc(sizeof(Node)); 78 if(new_node==NULL) 79 return -1; 80 81 new_node->letter=first_letter;//把节点插入到索引表中 82 new_node->next=current_node; 83 new_node->data=NULL; 84 *rootp=new_node; 85 current_node=new_node; 86 /*把新插入的节点赋值给current_node*/ 87 } 88 89 wordlink=¤t_node->data;//处理索引表中的字符和想要插入字符相等的情况 90 while((current_word=*wordlink)!=NULL) 91 //在二级链表中进行单词的插入,先找到插入位置 92 { 93 num=strcmp(current_word->word,the_word); 94 if(num>=0) 95 break; 96 wordlink=¤t_word->next; 97 } 98 if(current_word!=NULL&&num==0)//current_word不为空,且num为0,则word已经存在 99 return -1; 100 101 new_word=(Word*)malloc (sizeof( Word)); 102 if(new_word==NULL) 103 return -1; 104 105 new_word->word=(char*)malloc(strlen(the_word)+1);//给单词分配空间 106 if(new_word->word==NULL) 107 return -1; 108 109 strcpy(new_word->word,the_word);//插入单词到二级链表中 110 new_word->next=current_word; 111 *wordlink=new_word; 112 return 0; 113 } 114 void print(Node* rootp) 115 { 116 assert(rootp); 117 Node* tmp=rootp; 118 Word* word_tmp; 119 while(tmp!=NULL) 120 { 121 word_tmp=tmp->data; 122 printf("%c-------%c\n\n",tmp->letter,tmp->letter); 123 while(word_tmp!=NULL) 124 { 125 printf("%s-->",word_tmp->word); 126 word_tmp=word_tmp->next; 127 } 128 printf("NULL\n"); 129 printf("%c-------%c\n\n",tmp->letter,tmp->letter); 130 tmp=tmp->next; 131 } 132 133 }