一眼看尽双向链表

链表操作:大家好,这里是石侃侃的博客,这篇文章介绍了我对双向链表的一些理解

    链表的本质是指针的操作, 在这几行小程序解释了双向链表的本质

双向链表示例:
	#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:第二项成为第一项 */
		{
			g_ptNameHead = ptDel->next;
			/* 释放 */
			return;
		}
		else
		{
			ptCur = g_ptNameHead->next; /* 第二项开始 */
			while (ptCur)
			{
				if (ptCur == ptDel)     /* 找到 */
				{
					/* 从链表中删除 */
					ptPre  = ptCur->pre; 
					ptNext = ptCur->next;  
					ptPre->next = ptNext;  /* 前一个结构体的next = 本结构体的next = 后一个的头 */
					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;
			do {
				if (strcmp(ptCur->name, name) == 0)      /* do_while从头开始比较找到名字,返回名字所在结构体 */
					return ptCur;
				else
					ptCur = ptCur->next;
			}while (ptCur);
		}
		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();
					break;
				}
				case 'a':
				{
					add_one_name();
					break;
				}
				case 'd':
				{
					del_one_name();
					break;
				}
				case 'x':
				{
					return 0;
					break;
				}
				default:
				{
					break;
				}
			}
		}


		return 0;
	}


链表的本质在于对结构体指针变量的灵活运用

我们经常这样定义结构体

typedef struct NAME{
char *name;
struct NAME *pre;
struct NAME *next;

}T_Name, *PT_Name;

 *pre可以定位上一个链表

        *next;用来定位下一个链表

        *PT_Name是上一个链表的*next

猜你喜欢

转载自blog.csdn.net/zxpcus/article/details/79920018
今日推荐