双向链表
双向链表的删除操作反而简单一点,可以查找需要删除的节点,然后得到其前一节点与后一节点,然后将前节点的next指向后一节点,后一节点的pre指向前一节点即可完成,其他地方也没有太大的差异。
以下双向链表的源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct NAME{
char *name;
struct NAME *pre;
struct NAME *next;
}T_Name, *PT_Name;
static PT_Name g_ptNameHead;
void add_name(PT_Name ptNew)
{
PT_Name ptCur;
if (g_ptNameHead == NULL)
{
g_ptNameHead = ptNew;
}
else
{
ptCur = g_ptNameHead;
while (ptCur->next)
{
ptCur = ptCur->next;
}
ptCur->next = ptNew;
ptNew->pre = ptCur;
}
}
void del_name(PT_Name ptDel)
{
PT_Name ptCur;
PT_Name ptPre;
PT_Name ptNext;
if (g_ptNameHead == ptDel)
{
g_ptNameHead = ptDel->next;
/* 释放 */
return;
}
else
{
ptCur = g_ptNameHead->next;
while (ptCur)
{
if (ptCur == ptDel)
{
/* 从链表中删除 */
ptPre = ptCur->pre;//得到需要删除节点的前一节点
ptNext = ptCur->next;//得到需要删除节点的后一节点
ptPre->next = ptNext;
if (ptNext)
{
ptNext->pre = ptPre;
}
break;
}
else
{
ptCur = ptCur->next;
}
}
}
free(ptDel->name);
free(ptDel);
}
void add_one_name()
{
PT_Name ptNew;
char *str;
char name[128];
printf("enter the name:");
scanf("%s", name); //读入字符串
str = malloc(strlen(name) + 1);//此处包括字符串结束符
strcpy(str, name);
ptNew = malloc(sizeof(T_Name));
ptNew->name = str;
ptNew->pre = NULL;
ptNew->next = NULL;
add_name(ptNew);
}
PT_Name get_name(char *name)
{
PT_Name ptCur;
if (g_ptNameHead == NULL)
{
return NULL;
}
else
{
ptCur = g_ptNameHead;
while (ptCur)//当ptCur不为NULL
{
if (strcmp(ptCur->name, name) == 0)
return ptCur;
else
ptCur = ptCur->next;
}
}
return NULL;
}
void del_one_name()
{
PT_Name ptFind;
char name[128];
printf("enter the name:");
scanf("%s", name);
ptFind = get_name(name);
if (ptFind == NULL)
{
printf("do not have this name\n");
return ;
}
del_name(ptFind);
}
void list_all_name(void)
{
PT_Name ptCur;
int i = 0;
ptCur = g_ptNameHead;
while (ptCur)
{
printf("%02d : %s\n", i++, ptCur->name);
ptCur = ptCur->next;
}
}
int main(int argc, char **argv)
{
char c;
while (1)
{
printf("<l> List all the names\n");
printf("<a> add one name\n");
printf("<d> del one name\n");
printf("<x> exit\n");
printf("Enter the choise: ");
c = getchar();
switch (c)
{
case 'l':
{
list_all_name();
printf("\r\n");
break;
}
case 'a':
{
add_one_name();
break;
}
case 'd':
{
del_one_name();
break;
}
case 'x':
{
return 0;
break;
}
default:
{
break;
}
}
}
return 0;
}
单向链表
单向链表的删除不同于双向链表,需要先判断当前的节点的next是否是需要删除的节点,然后将当前节点的next指向需要删除的节点的next。如果next不存在,就置为NULL。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct NAME{
char *name;
//struct NAME *pre;
struct NAME *next;
}T_Name, *PT_Name;
static PT_Name g_ptNameHead;
void add_name(PT_Name ptNew)
{
PT_Name ptCur;
if (g_ptNameHead == NULL)
{
g_ptNameHead = ptNew;
}
else
{
ptCur = g_ptNameHead;
while (ptCur->next)
{
ptCur = ptCur->next;
}
ptCur->next = ptNew;
//ptNew->pre = ptCur;
}
}
void del_name(PT_Name ptDel)
{
PT_Name ptCur;
//PT_Name ptPre;
PT_Name ptNext;
if (g_ptNameHead == ptDel)//如果需要删除的是头节点,直接将第二个节点赋值给头节点
{
g_ptNameHead = ptDel->next;
/* 释放 */
return;
}
else
{
ptCur = g_ptNameHead;
ptNext = ptCur->next;
//ptNext = ptCur->next;
while (ptNext)
{
if (ptNext == ptDel)
{
/* 从链表中删除 */
//ptPre = ptCur->pre;//得到需要删除节点的前一节点
//ptNext = ptCur->next;//得到需要删除节点的后一节点
//ptPre->next = ptNext;
if (ptNext->next) //如果需要删除的节点下一个节点不为空 进行赋值操作
{
ptCur->next = ptNext->next;
//ptNext->pre = ptPre;
}
else //如果为空,当前节点的下一节点为空
{
ptCur->next = NULL;
}
break;
}
else
{
ptCur = ptCur->next;
ptNext = ptCur->next;
}
}
}
free(ptDel->name);
free(ptDel);
}
void add_one_name()
{
PT_Name ptNew;
char *str;
char name[128];
printf("enter the name:");
scanf("%s", name); //读入字符串
str = malloc(strlen(name) + 1);//申请空间长度要包括字符串结束符
strcpy(str, name);
ptNew = malloc(sizeof(T_Name));//分配节点空间注意使用指针来分配
ptNew->name = str;
//ptNew->pre = NULL;
ptNew->next = NULL;
add_name(ptNew);
}
PT_Name get_name(char *name)
{
PT_Name ptCur;
if (g_ptNameHead == NULL)
{
return NULL;
}
else
{
ptCur = g_ptNameHead;
while (ptCur)//当ptCur不为NULL
{
if (strcmp(ptCur->name, name) == 0)
return ptCur;
else
ptCur = ptCur->next;
}
}
return NULL;
}
void del_one_name()
{
PT_Name ptFind;
char name[128];
printf("enter the name:");
scanf("%s", name);
ptFind = get_name(name);
if (ptFind == NULL)
{
printf("do not have this name\n");
return ;
}
del_name(ptFind);
}
void list_all_name(void)
{
PT_Name ptCur;
int i = 0;
ptCur = g_ptNameHead;
while (ptCur)
{
printf("%02d : %s\n", i++, ptCur->name);
ptCur = ptCur->next;
}
}
int main(int argc, char **argv)
{
char c;
while (1)
{
printf("<l> List all the names\n");
printf("<a> add one name\n");
printf("<d> del one name\n");
printf("<x> exit\n");
printf("Enter the choise: ");
c = getchar();
switch (c)
{
case 'l':
{
list_all_name();
printf("\r\n");
break;
}
case 'a':
{
add_one_name();
break;
}
case 'd':
{
del_one_name();
break;
}
case 'x':
{
return 0;
break;
}
default:
{
break;
}
}
}
return 0;
}