对于数据结构问题,首先来谈谈关于链表的问题,关于链表的操作无非就是生成,遍历,增加,删除,其他的操作都是建立在这4种操作上面的。理解链表关键是关于指针节点的操作,
1.定义链表数据结构与动态分配内存
定义链表节点,拿数字作为值为例子
typedef struct Node
{
int data;
Node* next;
}Node
Node* p=(Node*)malloc(sizeof(Node));
2.生成一个链表
生成链表其实就是定义一个新节点不断往前一个节点插入的过程,这里需要定义3个指向链表节点指针就够了,一个保存头节点作为函数的返回值;一个保存上一节点,用来进行连接链表;一个定义新的节点,用来生成新的节点。
代码如下:
Node* Create() //定义了一个创建链表的函数,返回链表的头指针
{
Node* p; //这个指针用来定义新节点,需要不断新生成
Node* pHead; //这个指针用来保存头结点,其实就使用一次
Node* pTemp; //临时指针,这个指针用来保存p1节点的上一节点,用来连接链表
p=(Node*)malloc(sizeof(Node));
if(p==NULL)
{
printf("初始化错误");
return NULL;
}
memset(p1,0,sizeof(p));
scanf("%d",&p->data);
p->next=NULL;
//移动指针
pHead=p; //pHead指针就用了这一次,做为返回值就行
//用来保存头节点
pTemp=p;
while(p->data!=0) //输入0链表生成完成
{
p=(Node*)malloc(sizeof(Node)); //不断开辟新的节点
memset(p,0,sizeof(p));
scanf("%d",&p->data);
p->next=NULL;
pTemp->next=p //核心语句,连接链表,这里的pTemp其实是是新生成p节点的上一节点,链表生成的关键
pTemp=p; //移动指针,为下一次连接做准备
}
return pHead;
}
3.遍历链表,遍历链表其实很简单,就是一个指针不断下移的过程。
p=p->next;
当p为空是就退出,传入链表的头指针.
void Traversal(Node *p)
{
if(p==NULL)
{
printf("链表不存在");
return;
}
while(p!=NULL)
{
printf("%d",p->data);
p=p->next;//核心代码,遍历链表
}
printf("\n");
}
3.插入某一节点,插入节点就3部分,定义新节点,查找插入位置,重新;连接
void Insert(Node** pHead,int Pos,int num)
{
int Size=0;
Node* pTemp;
pTemp=*pHead;
if(*pHead==NULL)
{
printf("链表不存在");
return;
}
//第一步定义新的需要插入的节点
Node* p;
p=(Node*)malloc(sizeof(Node));
p->data=num;
//第二步查找要插入的位置
while(pTemp->next!=NULL)
{
++Size;
if(Size==Pos)
{
//找到了指定的插入位置
//第三步 重新连接
p->next=pTemp->next;
pTemp->next=p;
//上面2部插入的核心代码,注意:顺序不能弄反了,一定要先连后节点,再连前节点,如果反了的话,像这样
// px->next=p;
// p->next=px->next;
// 其实就是
// p->next=p;产生无限循环,好比狗追尾巴一样,一直在原地打转
break;
}
pTemp=pTemp->next;
}
if(Size<Pos)
{
printf("插入的位置不正确");
return;
}
}
4.删除某一节点
删除节点分2部分,查找与断链重连,在这里我把删除头节点单独拿出来写了,注意这里删除的顺序我还是从0开始,并不是从1开始的。
Node* DeleteNode(Node** pHead,int Pos)
{
int Size=0;
Node* pTemp;
pTemp=*pHead;
if(*pHead==NULL)
{
printf("链表不存在");
return NULL;
}
while(pTemp!=NULL)
{
if(Pos==0)
{
*pHead=(*pHead)->next;
free(pTemp);
return *pHead;
}
else
{
++Size;
if(Size==Pos)
{
Node* pDelete=pTemp->next;
pTemp->next=pDelete->next; //核心代码,定义一个指向需要删除的节点的指针,把删除节点前一节点的指针连接删除节点的后继节点即可,
free(pDelete); //删除节点
return *pHead;
break;
}
pTemp=pTemp->next;
}
}
if(Size<Pos)
{
printf("删除的位置不正确");
return *pHead;
}
}
总结:链表的操作,定义临时节点与新节点,新节点用来分配内存,创建链表,临时节点用来遍历链表,链表的核心语句其实就只有下面这几行代码
Node* p;
p=(Node*)malloc(sizeof(Node));
p=p->next;
p->next=pTemp->next;
pTemp->next=p;
Node* pDelete=pTemp->next;
pTemp->next=pDelete->next