/*
* @Author: suifengtec
* @Date: 2017-09-02 16:06:33
* @Last Modified by: suifengtec
* @Last Modified time: 2017-09-02 20:47:13
**/
/*
字符单向链表
gcc -o a.exe main.c && a
*/
#include
#include
#include
// 声明一个自包含结构体listNode,并把它定义为类型 ListNode
typedef struct listNode{
char data;
struct listNode *nextPtr;
} ListNode;
// 为 ListNode 的指针定义一个类型 ListNodePtr
typedef ListNode *ListNodePtr;
// 引导说明
void bootstrap(void);
// 插入到链表,这里按照字符的 ASCII 码插入
// 参数分别为当前节点的指针和元素的值
void insert(ListNodePtr *sPtr, char value);
// 链表是否为空
bool isEmpty(ListNodePtr sPtr);
// 从链表中删除特定的元素值,返回是否删除成功的布尔值
// 每次只删除1个,即使链表中有两个AA, 在 value 为 A 时, 也只删除第一个
bool delete(ListNodePtr *sPtr, char value);
// 打印链表
void printList(ListNodePtr currentPtr);
int main(void) {
// 起始指针/当前指针
ListNodePtr startPtr = NULL;
// 在引导说明中已经说明了,只能取1,2,3 中的一个值,其它的整数将会被认为是字符
unsigned int choice;
// 字符
char item;
// 引导说明
bootstrap();
// 获取用户输入的 1 或 2 或 3 或者字符,或者无空格的不含1和2和3的字符串
printf("%s","?");
scanf("%u", &choice);
// 不为3 时
while(choice!=3){
switch(choice){
// 1 表示向链表中插入字符
case 1:
/*
每次输入一个字符
还支持输入一个不含空格的字符串
如
HelloChina!
链表为
!-->C-->H-->a-->h-->i-->i-->NULL
*/
printf("%s","Enter a character:");
scanf("\n%c", &item);
insert(&startPtr,item);
printList(startPtr);
break;
// 2 表示从链表中删除字符,链表为空或者没有要删除的字符时,给出错误提示。
//如果这个字符串中的字符全都存在于链表的话
// 也可以一次性删除输入的不含1和2和3的不含空格的字符串,
case 2:
if(!isEmpty(startPtr)){
printf("%s","Enter a character to be deleted:");
scanf("\n%c", &item);
if(delete(&startPtr, item)){
printf("\'%c\' has be deleted.\n", item);
printList(startPtr);
}else{
printf("not found \'%c\'\n", item);
}
}
else{
puts("the list is empty?");
}
break;
// 后备,因为不可能到这里的
case 3:
puts("invalid option!");
bootstrap();
break;
}
/*bootstrap();*/
printf("%s","?");
scanf("%u", &choice);
}
return 0;
}
void bootstrap(void)
{
printf(
"Enter your choice:\n" "1 = insert an element to the list\n"
"2 = delete an element from the list\n"
"3 = Game Over.\n"
);
}
void insert( ListNodePtr *sPtr, char value )
{
ListNodePtr newPtr = malloc(sizeof(ListNode));
if( newPtr != NULL ){
newPtr->data = value;
newPtr->nextPtr = NULL;
ListNodePtr prePtr = NULL;
ListNodePtr currentPtr = *sPtr;
while( currentPtr != NULL && value > currentPtr->data){
prePtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}
if(prePtr==NULL){
newPtr->nextPtr = *sPtr;
*sPtr = newPtr;
}else{
prePtr->nextPtr = newPtr;
newPtr->nextPtr = currentPtr;
}
}else{
printf("%c not inserted. No memory availabe.\n", value);
}
}
bool delete(ListNodePtr *sPtr, char value)
{
if(value == (*sPtr)->data){
ListNodePtr tmpPtr = *sPtr;
*sPtr = (*sPtr)->nextPtr;
free(tmpPtr);
return true;
}
else{
ListNodePtr prePtr = *sPtr;
ListNodePtr currentPtr = (*sPtr)->nextPtr;
while(currentPtr != NULL && currentPtr->data != value){
prePtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}
if(currentPtr!=NULL){
ListNodePtr tmpPtr = currentPtr;
prePtr->nextPtr = currentPtr->nextPtr;
free(tmpPtr);
return true;
}
}
return false;
}
bool isEmpty(ListNodePtr sPtr)
{
return sPtr == NULL?true:false;
}
void printList(ListNodePtr currentPtr)
{
if(isEmpty(currentPtr)){
puts("List is empty?");
}
else{
puts("The list is :\n");
while(currentPtr->nextPtr!=NULL){
printf("%c-->", currentPtr->data);
currentPtr = currentPtr->nextPtr;
}
puts("NULL\n");
}
}
/*EOF*/
单向字符链表的C语言实现。