程序为(与课本不同,稍有改动)
#include
#include
struct listNode {
char data;
struct listNode *nextPtr;
};
typedef struct listNode ListNode;
typedef ListNode *ListNodePtr;
void insert (ListNodePtr *sPtr,char value);
char delete (ListNodePtr *sPtr,char value);
int isEmpty(ListNodePtr sPtr);
void printList(ListNodePtr currentPtr);
void instructions (void);
int main()
{
ListNodePtr startPtr=NULL;
char item;
unsigned int choice;
char mm;
instructions();
printf("%s","?");
mm=getchar();
while(getchar()!='\n')
continue;
choice=(unsigned int)mm-48;
while(choice!=3){
switch (choice) {
case 1:
printf("%s","Enter a character:");
item=getchar();
while(getchar()!='\n')
continue;
insert(&startPtr,item);
printList(startPtr);
break;
case 2:
if(!isEmpty(startPtr)){
printf("%s","Enter character to be delete: ");
item=getchar();
while(getchar()!='\n')
continue;
if(delete(&startPtr,item)){
printf("%c deleted.\n",item);
printList(startPtr);
}else
{
printf("%c not found.\n\n",item);
}
}
else{
puts("List is empty.");
}
break;
default:
puts("Invallid choice .\n");
instructions();
break;
}
printf("%s\n","?");
mm=getchar();
while(getchar()!='\n')
continue;
choice=(unsigned int)mm-48;
}
puts("End of run.");
}
void instructions()
{
puts("Enter your choice:\n"
" 1 to insert an element into the list.\n"
" 2 to delete an element from the list.\n"
" 3 to end.");
}
void insert(ListNodePtr *sPtr,char value)
{
ListNodePtr newPtr=malloc(sizeof (ListNode));
if(newPtr != NULL){
newPtr->data=value;
newPtr->nextPtr=NULL;
ListNodePtr previousPtr=NULL;
ListNodePtr currentPtr=*sPtr;
while(currentPtr != NULL && value >currentPtr->data){
previousPtr=currentPtr;
currentPtr=currentPtr->nextPtr;
}
if(previousPtr==NULL){
newPtr->nextPtr=*sPtr;
*sPtr=newPtr;
}
else {
previousPtr->nextPtr=newPtr;
newPtr->nextPtr=currentPtr;
}
}else{
printf("%c not inserted.No memory available.\n",value);
}
}
char delete (ListNodePtr *sPtr,char value)
{
if(value==(*sPtr)->data){
ListNodePtr tempPtr=*sPtr;
*sPtr=(*sPtr)->nextPtr;
free(tempPtr);
return value;
}
else
{
ListNodePtr previousPtr=*sPtr;
ListNodePtr currentPtr=(*sPtr)->nextPtr;
while(currentPtr!=NULL&&value!=currentPtr->data)
{
previousPtr=currentPtr;
currentPtr=currentPtr->nextPtr;
}
if(currentPtr!=NULL)
{
ListNodePtr tempPtr=currentPtr;
previousPtr->nextPtr=currentPtr->nextPtr;
free(tempPtr);
return value;
}
}
}
int isEmpty(ListNodePtr sPtr){
return sPtr==NULL;
}
void printList(ListNodePtr currentPtr)
{
if(isEmpty(currentPtr)){
puts("List is empty.");
}else
{
puts("The list is :");
while(currentPtr !=NULL)
{
printf("%c --> ",currentPtr->data);
currentPtr = currentPtr->nextPtr;
}
puts("NULL\n");
}
}
insert函数共分为三部分
1.用malloc()抓取一个新节点
2.用while循环顺藤摸瓜摸到尾部的子节点
3.将1.抓取的节点连接到链表上
void insert(ListNodePtr *sPtr,char value)
{
ListNodePtr newPtr=malloc(sizeof (ListNode));
if(newPtr != NULL){
newPtr->data=value;
newPtr->nextPtr=NULL;
ListNodePtr previousPtr=NULL;
ListNodePtr currentPtr=*sPtr;
while(currentPtr != NULL && value >currentPtr->data){
previousPtr=currentPtr;
currentPtr=currentPtr->nextPtr;
}
if(previousPtr==NULL){
newPtr->nextPtr=*sPtr;
*sPtr=newPtr;
}
else {
previousPtr->nextPtr=newPtr;
newPtr->nextPtr=currentPtr;
}
}else{
printf("%c not inserted.No memory available.\n",value);
}
}
malloc()函数负责在内存中抓取sizeof (ListNode)的空间。并定义成ListNode型;
sPtr保存所抓取的空间的地址。
ListNodePtr previousPtr=NULL;//创建一个ListNode型指针指向NULL
ListNodePtr currentPtr=*sPtr;//创建一个ListNode指向表头
while(currentPtr != NULL && value >currentPtr->data)
顺藤摸瓜找到表尾或者发现一个value应该在的位置(比如value为5,当发现currentPtr->data为6时,说明value所在的节点应该在currentPtr指向节点的前面,且在previousPtr指向节点的后面)
if(previousPtr==NULL)
如果此时是链表第一个节点,就将该节点的地址赋值给主函数的startPtr。
如果是找到了表尾或应该在的位置,将上一个节点指向新节点,将新节点指向下一个节点。
注:
至于为什么insert函数的形参为ListNodePtr *sPtr,我认为只有实参为&startPtr时,即(带&),才能在不返回值的情况下改变主函数的startPtr。
delete()函数同理。
char delete (ListNodePtr *sPtr,char value)
{
if(value==(*sPtr)->data){
ListNodePtr tempPtr=*sPtr;
*sPtr=(*sPtr)->nextPtr;
free(tempPtr);
return value;
}
else
{
ListNodePtr previousPtr=*sPtr;
ListNodePtr currentPtr=(*sPtr)->nextPtr;
while(currentPtr!=NULL&&value!=currentPtr->data)
{
previousPtr=currentPtr;
currentPtr=currentPtr->nextPtr;
}
if(currentPtr!=NULL)
{
ListNodePtr tempPtr=currentPtr;
previousPtr->nextPtr=currentPtr->nextPtr;
free(tempPtr);
return value;
}
}
}
delete函数共分为两部分
1.找到节点
2.删除节点
if(value==(*sPtr)->data)
是否头节点为所要找节点
while(currentPtr!=NULL&&value!=currentPtr->data)
没有找到或找到
ListNodePtr tempPtr=*sPtr;
//tempPtr指向要删除的节点
*sPtr=(*sPtr)->nextPtr;
//头指针指向第二个节点作为头节点
free(tempPtr);
//删除节点
return value;
//告诉主函数已删除
ListNodePtr tempPtr=currentPtr;
//tempPtr指向要删除的节点
previousPtr->nextPtr=currentPtr->nextPtr;
//上一个节点指向下下节点
free(tempPtr);
//删除节点
return value;
//告诉主函数已删除
如果未删除,函数默认返回0