您的位置:首页 > 其它

单链表的插入与删除

2016-06-20 15:32 387 查看
转自: http://blog.csdn.net/xubin341719/article/details/7091979
参考:http://www.itxyz.net/3jk/c/2010/0820/11016.html

最近不是太忙,整理些东西,工作也许用得到。

在链表这种特殊的数据结构中,链表的长短需要根据具体情况来设定,当需要保存数据时向系统申请存储空间,并将数据接入链表中。对链表而言,表中的数据可以依此接到表尾或连结到表头,也可以视情况插入表中;对不再需要的数据,将其从表中删除并释放其所占空间,但不能破坏链表的结构。这就是下面将介绍的链表的插入与删除。

1. 链表的删除

如创建一个学生学号及姓名的单链表,即节点包括学生学号、姓名及指向下一个节点的指针,链表按学生的学号排列。再从键盘输入某一学生姓名,将其从链表中删除。

首先定义链表的结构:

从链表中删除一个节点有三种情况,即删除链表头节点、删除链表的中间节点、删除链表的尾节点。题目给出的是学生姓名,则应在链表中从头到尾依此查找各节点,并与各节点的学生姓名比较,若相同,则查找成功,否则,找不到节点。由于删除的节点可能在链表的头,会对链表的头指针造成丢失,所以定义删除节点的函数的返回值定义为

返回结构体类型的指针。

[cpp]
view plain
copy

print?

struct node *delet(head,pstr)/*以head为头指针,删除pstr所在节点*/  
struct node *head;  
char *pstr;  
{  
    struct node*temp,*p;  
    temp  = head;  /* 链表的头指针*/  
    if (head==NULL)/*链表为空*/   
        printf("\nListis null!\n");  
    else /*非空表*/  
    {  
                temp = head;  
        while (strcmp(temp->str,pstr)!=0&&temp->next!=NULL)/* 若节点的字符串与输入字符串不同,并且未到链表尾*/  
        {  
            p = temp;  
            temp = tmep->next;/* 跟踪链表的增长,即指针后移*/  
        }  
        if(strcmp(temp->str,pstr)==0) /*找到字符串*/  
        {  
        if(temp==head) { /* 表头节点*/  
            printf("delete string :%s\n",temp->str);  
            head = head->next;  
            free(temp);/*释放被删节点*/  
        }  
        else  
        {  
            p->next=temp->next; /*表中节点*/  
            printf("delete string :%s\n",temp->str);  
            free(temp);  
        }  
    }  
    else  
    printf("\nno find string!\n");/*没找到要删除的字符串*/  
    }  
    return(head);  
}  

struct node *delet(head,pstr)/*以head为头指针,删除pstr所在节点*/
struct node *head;
char *pstr;
{
struct node*temp,*p;
temp  = head;  /* 链表的头指针*/
if (head==NULL)/*链表为空*/
printf("\nListis null!\n");
else /*非空表*/
{
temp = head;
while (strcmp(temp->str,pstr)!=0&&temp->next!=NULL)/* 若节点的字符串与输入字符串不同,并且未到链表尾*/
{
p = temp;
temp = tmep->next;/* 跟踪链表的增长,即指针后移*/
}
if(strcmp(temp->str,pstr)==0) /*找到字符串*/
{
if(temp==head) { /* 表头节点*/
printf("delete string :%s\n",temp->str);
head = head->next;
free(temp);/*释放被删节点*/
}
else
{
p->next=temp->next; /*表中节点*/
printf("delete string :%s\n",temp->str);
free(temp);
}
}
else
printf("\nno find string!\n");/*没找到要删除的字符串*/
}
return(head);
}


2. 链表的插入

首先定义链表的结构:

[cpp]
view plain
copy

print?

struct  
{  
int num; /*学生学号* /  
char str[20]; /*姓名* /  
struct node *next;  
} ;  

struct
{
int num; /*学生学号* /
char str[20]; /*姓名* /
struct node *next;
} ;


在建立的单链表中,插入节点有三种情况,如图所示;



插入的节点可以在表头、表中或表尾。假定我们按照以学号为顺序建立链表,则插入的节点依次与表中节点相比较,找到插入位置。由于插入的节点可能在链表的头,会对链表的头指针造成修改,所以定义插入节点的函数的返回值定义为返回结构体类型的指针。节点的插入函数如下:

[cpp]
view plain
copy

print?

struct node *insert(head,pstr,n) /*插入学号为n、姓名为p s t r 的节点*/  
struct node *head; /*链表的头指针*/  
char *pstr;   
int n;  
{  
    struct node *p1,*p2,*p3;  
    p1=(struct node*)malloc(sizeof(struct node))/*分配一个新节点*/  
    strcpy(p1->str,pstr); /*写入节点的姓名字串*/  
    p1->num = n; /* 学号*/  
    p2 = head;  
    if(head==NULL) /* 空表*/  
    {  
        head=p1;   
        p1->next=NULL;/*新节点插入表头*/  
    }  
    else/*非空表*/  
    {   
        while(n>p2->num&&p2->next!=NULL)  
        /*输入的学号小于节点的学号,并且未到表尾*/  
        {  
            p3 = p2;  
            p2 = p2->next;/* 跟踪链表增长*/  
        }  
        if(n<=p2->num) /*找到插入位置*/   
        if(head==p2) /* 插入位置在表头*/  
        {  
            head = p1;  
            p1->next = p2;  
        }  
        else  
        { /*插入位置在表中*/  
            p3->next = p1;  
            p1->next = p2;  
        }  
        else  
        { /*插入位置在表尾*/  
            p2->next = p1;  
            p1->next = NULL;  
        }  
    }  
    return(head); /* 返回链表的头指针*/  
}  

struct node *insert(head,pstr,n) /*插入学号为n、姓名为p s t r 的节点*/
struct node *head; /*链表的头指针*/
char *pstr;
int n;
{
struct node *p1,*p2,*p3;
p1=(struct node*)malloc(sizeof(struct node))/*分配一个新节点*/
strcpy(p1->str,pstr); /*写入节点的姓名字串*/
p1->num = n; /* 学号*/
p2 = head;
if(head==NULL) /* 空表*/
{
head=p1;
p1->next=NULL;/*新节点插入表头*/
}
else/*非空表*/
{
while(n>p2->num&&p2->next!=NULL)
/*输入的学号小于节点的学号,并且未到表尾*/
{
p3 = p2;
p2 = p2->next;/* 跟踪链表增长*/
}
if(n<=p2->num) /*找到插入位置*/
if(head==p2) /* 插入位置在表头*/
{
head = p1;
p1->next = p2;
}
else
{ /*插入位置在表中*/
p3->next = p1;
p1->next = p2;
}
else
{ /*插入位置在表尾*/
p2->next = p1;
p1->next = NULL;
}
}
return(head); /* 返回链表的头指针*/
}


实例:

创建包含学号、姓名节点的单链表。其节点数任意个,表以学号为序,低学号的在前,高学号的在后,以输入姓名为空作结束。在此链表中,要求删除一个给定姓名的节点,并插入一个给定学号和姓名的节点。

[cpp]
view plain
copy

print?

# include <stdlib.h>  
# include <malloc.h>  
struct node /*节点的数据结构*/  
{  
    int num;  
    char str[20];  
    struct node *next;  
};  
/* * * * * * * * * * * * * * * * * * * * * * * * * * * */  
main( )  
{  
    /*函数声明*/  
    struct node *creat();  
    struct node *insert();  
    struct node *delet();  
    void print( );  
    struct node *head;  
    char str[20];  
    int n;  
    head=NULL; /*做空表*/  
    head=creat(head); /*调用函数创建以head 为头的链表*/  
    print(head);/*调用函数输出节点*/  
    printf("\n input inserted num,name:\n");  
    gets(str); /*输入学号*/  
    n=atoi(str);  
    gets(str); /*输入姓名*/  
    head=insert(head, str, n); /*节点插入链表*/  
  
    print(head);  
    printf("\n input deleted name:\n");  
    gets(str); /*输入被删姓名*/  
    head=delet(head,str); /*用函数删除节点*/  
    print(head); /*调用函数输出节点*/  
    return;  
}  
/* * * * * * * * * * * * * * * * * * * * * */  
/* * * 创建链表* * * * * * * * * * * */  
struct node *creat(struct node *head)  
{  
    char temp[30];  
    struct node *pl,*p2;  
    pl=p2=(struct node*)malloc(sizeof(struct node));  
    printf("input num, name: \n");  
    printf("exit:double times Enter!\n");  
    gets(temp);  
    gets(pl->str);  
    pl->num=atoi(temp);  
    pl->next = NULL ;  
    while(strlen(pl->str)>0)  
    {  
        if(head==NULL)//if the chain is null  
             head= pl;//  
        else   
            p2->next=pl;//set the p2->next NULL  
        p2 = pl;//  
    pl=(struct node*)malloc(sizeof(struct node));  
    printf ("input num, name: \n");  
    printf("exit:double times Enter!\n");   
    gets(temp);  
    gets(pl->str);  
    pl->num=atoi(temp);  
    pl->next= NULL;   
    }         
    return head;  
}  
/* * * * * * * * * * * * * * * * * * * */  
/* * * * * * * * * * 插入节点* * * * * * * * * */  
struct node *insert(head, pstr,n)  
struct node *head;  
char *pstr;  
int n;  
{  
    struct node *pl,*p2,*p3;  
    pl=(struct node*)malloc(sizeof(struct node));  
    strcpy (pl->str, pstr);  
    pl->num = n;  
    p2 = head;   
    if(head == NULL)  
  
    {  
        head = pl;   
        pl->next = NULL;  
    }  
    else  
    {  
    while (n>p2->num&&p2->next!=NULL)  
    {  
        p3 = p2;  
        p2= p2->next;  
    }  
    if (n<=p2->num)  
    if (head==p2)  
    {  
        head = pl;  
        pl->next = p2;  
    }  
    else  
    {  
        p3->next = pl;  
        pl->next=  p2;   
    }  
    else  
    {  
        p2->next= pl;  
        pl->next = NULL;  
    }  
}  
    return(head);  
}  
/* * * * * * * * * * * * * * * * * * * * * * * * */  
  
  
/* * * * * 删除节点* * * * * * * * * * * * */  
struct node *delet (head, pstr)  
struct node *head;  
char *pstr;  
{  
    struct node *temp,*p;  
    temp =head;  
    if (head==NULL)  
    printf("\nList is null!\n");  
    else  
    {  
        temp = head;  
        while(strcmp(temp->str,pstr)!= 0 && temp->next!=NULL)  
        {  
            p = temp;  
            temp= temp->next;  
        }  
        if(strcmp(temp->str,pstr)== 0)  
        {  
            if (temp== head)  
            {  
                head = head->next;  
                free(temp);  
            }  
            else  
            {  
                p->next =temp->next;  
                printf("delete string :%s\n",temp->str);  
                free(temp);  
            }  
        }  
        else   
            printf("\nno find string!\n");  
    }  
    return(head);  
}  
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */  
/* * * * * * * * * * 链表各节点的输出* * * * * * * * * */    
void print(struct node *head)  
{  
struct node *temp;  
temp = head;  
printf("\n output strings:\n");  
while (temp!=NULL)  
{  
printf("\n%d-----%s\n",temp->num,temp->str);  
temp= temp->next;  
}  
return;  
}   

# include <stdlib.h>
# include <malloc.h>
struct node /*节点的数据结构*/
{
int num;
char str[20];
struct node *next;
};
/* * * * * * * * * * * * * * * * * * * * * * * * * * * */
main( )
{
/*函数声明*/
struct node *creat();
struct node *insert();
struct node *delet();
void print( );
struct node *head;
char str[20];
int n;
head=NULL; /*做空表*/
head=creat(head); /*调用函数创建以head 为头的链表*/
print(head);/*调用函数输出节点*/
printf("\n input inserted num,name:\n");
gets(str); /*输入学号*/
n=atoi(str);
gets(str); /*输入姓名*/
head=insert(head, str, n); /*节点插入链表*/

print(head);
printf("\n input deleted name:\n");
gets(str); /*输入被删姓名*/
head=delet(head,str); /*用函数删除节点*/
print(head); /*调用函数输出节点*/
return;
}
/* * * * * * * * * * * * * * * * * * * * * */
/* * * 创建链表* * * * * * * * * * * */
struct node *creat(struct node *head)
{
char temp[30];
struct node *pl,*p2;
pl=p2=(struct node*)malloc(sizeof(struct node));
printf("input num, name: \n");
printf("exit:double times Enter!\n");
gets(temp);
gets(pl->str);
pl->num=atoi(temp);
pl->next = NULL ;
while(strlen(pl->str)>0)
{
if(head==NULL)//if the chain is null
head= pl;//
else
p2->next=pl;//set the p2->next NULL
p2 = pl;//
pl=(struct node*)malloc(sizeof(struct node));
printf ("input num, name: \n");
printf("exit:double times Enter!\n");
gets(temp);
gets(pl->str);
pl->num=atoi(temp);
pl->next= NULL;
}
return head;
}
/* * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * 插入节点* * * * * * * * * */
struct node *insert(head, pstr,n)
struct node *head;
char *pstr;
int n;
{
struct node *pl,*p2,*p3;
pl=(struct node*)malloc(sizeof(struct node));
strcpy (pl->str, pstr);
pl->num = n;
p2 = head;
if(head == NULL)

{
head = pl;
pl->next = NULL;
}
else
{
while (n>p2->num&&p2->next!=NULL)
{
p3 = p2;
p2= p2->next;
}
if (n<=p2->num)
if (head==p2)
{
head = pl;
pl->next = p2;
}
else
{
p3->next = pl;
pl->next=  p2;
}
else
{
p2->next= pl;
pl->next = NULL;
}
}
return(head);
}
/* * * * * * * * * * * * * * * * * * * * * * * * */

/* * * * * 删除节点* * * * * * * * * * * * */
struct node *delet (head, pstr)
struct node *head;
char *pstr;
{
struct node *temp,*p;
temp =head;
if (head==NULL)
printf("\nList is null!\n");
else
{
temp = head;
while(strcmp(temp->str,pstr)!= 0 && temp->next!=NULL)
{
p = temp;
temp= temp->next;
}
if(strcmp(temp->str,pstr)== 0)
{
if (temp== head)
{
head = head->next;
free(temp);
}
else
{
p->next =temp->next;
printf("delete string :%s\n",temp->str);
free(temp);
}
}
else
printf("\nno find string!\n");
}
return(head);
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * 链表各节点的输出* * * * * * * * * */
void print(struct node *head)
{
struct node *temp;
temp = head;
printf("\n output strings:\n");
while (temp!=NULL)
{
printf("\n%d-----%s\n",temp->num,temp->str);
temp= temp->next;
}
return;
}


运行结果:

[cpp]
view plain
copy

print?

root@android-virtual-machine:/uniteq_smb/test# ./test1  
input num, name:   
exit:double times Enter!  
11  
aa  
input num, name:   
exit:double times Enter!  
12  
bb  
input num, name:   
exit:double times Enter!  
  
  
  
 output strings:  
  
11-----aa  
  
12-----bb  
  
 input inserted num,name:  
13  
cc  
  
 output strings:  
  
11-----aa  
  
12-----bb  
  
13-----cc  
  
 input deleted name:  
aa  
  
 output strings:  
  
12-----bb  
  
13-----cc  

root@android-virtual-machine:/uniteq_smb/test# ./test1
input num, name:
exit:double times Enter!
11
aa
input num, name:
exit:double times Enter!
12
bb
input num, name:
exit:double times Enter!

output strings:

11-----aa

12-----bb

input inserted num,name:
13
cc

output strings:

11-----aa

12-----bb

13-----cc

input deleted name:
aa

output strings:

12-----bb

13-----cc
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: