您的位置:首页 > 其它

链表的基本操作

2015-07-20 23:11 190 查看
有链表的创建,增加、删除节点,链表的逆序、排序和销毁等。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct tag
{
int m_val;
char m_buf[32];
struct tag* m_next;
}NODE,*pNODE;

void link_init_tail(pNODE* phead);
void link_init_head(pNODE* phead);
void link_show(pNODE phead);
void link_destory(pNODE* phead);
void link_init_sort(pNODE* pphead);
void link_delete(pNODE* phead, int val);
void link_reverse(pNODE* phead);
int main(int argc,  char* argv[])
{
int val = 0;
pNODE phead = NULL;

link_init_tail(&phead);
link_show(phead);
//link_init_head(&phead);

//link_init_sort(&phead);
putchar(10);
link_reverse(&phead);

//link_destory(&phead);

link_show(phead);
printf("\n");

while(scanf("%d", &val) == 1)
{
link_delete(&phead, val);
link_show(phead);
printf("\n");
}

system("pause");
return 0;
}

void link_init_tail(pNODE* phead)
{
int val ;
pNODE  pnew = NULL, ptail = NULL;
while(scanf("%d",&val) == 1)
{
pnew = (pNODE)calloc(1,sizeof(NODE));
pnew->m_val = val;
if(*phead == NULL)
{
*phead = pnew;
ptail = pnew;
}else
{
ptail->m_next = pnew;
ptail = pnew;
}
}
}
void link_init_head(pNODE* phead)
{
int val ;
pNODE  pnew = NULL;
while(scanf("%d",&val) == 1)
{
pnew = (pNODE)calloc(1,sizeof(NODE));
pnew->m_val = val;
pnew->m_next = *phead;
*phead = pnew;
}
}

void link_init_sort(pNODE* phead)
{
int val;
pNODE pnew, pcur, ppre;
while (scanf("%d",&val) == 1)
{
pnew = (pNODE)calloc(1,sizeof(NODE));
pnew->m_val = val;
pcur = *phead;
ppre = NULL;
while(pcur&&pcur->m_val < pnew->m_val)
{
ppre = pcur;
pcur = pcur->m_next;

}
if(ppre == NULL)
{
pnew->m_next = *phead;
*phead = pnew;

}else
{
pnew->m_next = pcur;
ppre->m_next = pnew;

}
}
}

void link_show(pNODE phead)
{
pNODE pcur;
pcur = phead;
while(pcur != NULL)
{
printf("%3d",pcur->m_val);
pcur = pcur->m_next;

}
}
void link_destory(pNODE* phead)
{
pNODE pcur, ptmp = NULL;
pcur = *phead;
while(pcur)
{
ptmp = pcur ;
pcur = pcur->m_next;
free(ptmp);

}
*phead = NULL;
}

void link_delete(pNODE* phead, int val)
{
pNODE ppre, pcur;
pcur = *phead;
ppre = NULL;
while(pcur && pcur->m_val != val)
{
ppre = pcur;
pcur = pcur->m_next;

}
if(pcur == NULL)
{
printf("Not exist");
}else
{
if(ppre == NULL)
{
*phead = pcur->m_next;
free(pcur);
}else
{
ppre->m_next = pcur->m_next;
free(pcur);

}
}
}

void link_reverse(pNODE* phead)
{
pNODE old_head = NULL;
pNODE new_head = NULL;
pNODE cur = *phead;

while(cur != NULL)
{
old_head = cur->m_next;
cur->m_next = new_head;
new_head = cur;
cur = old_head;
}
*phead = new_head;
printf("After reverse:\n");
//link_show(*phead);
}


链表反转的思路:

取出原始链表的第一个节点A,然后将该节点作为新链表的头节点。

现在状态为

原始链表:B->C->D->E

新链表:A

然后同上,变为了下面的状态

原始链表:C->D->E

新链表: B->A

原始链表:D->E

新链表: C->B->A

原始链表:E

新链表: D->C->B->A

原始链表:

新链表: E->D->C->B->A

很显然,对原始链表遍历一次,就完成了这个工作,所以这个算法的复杂度为O(n)。

通过对上面状态的变化分析,只要我们知道原始链表和新链表的头节点,我们就可以从原始链表取出第一个节点,然后将节点插入到新链表的第一个位置,由于两个链表的头结点现在都已经变化,所以我们不能丢失新头节点的地址。所以,我们要设置两个变量分别记录两个链表的头结点。下面程序中的old_head和 new_head分别表示原始链表的头节点和新链表的头节点。

程序如下,实现了迭代方式和递归方式:

#include <stdio.h>
#include <malloc.h>
typedef struct Node{
int data;
struct Node* next;
}Node;
#define LIST_LEN     10     //链表长度
Node * List = NULL;          //链表
//迭代方式
void reverse_ite(Node * list){
Node * old_head = NULL;         //原来链表的头
Node * new_head = NULL;      //新链表的头
Node * cur = list;      //获得原来链表的头
//每次将原来链表的头取出,并插入到新链表中,并且是新链表的头
while(cur != NULL){
old_head = cur->next;    //将原来链表的头取出,并将第二个节点作为头节点
cur->next = new_head;   //将取出的头设为新链表的头

new_head = cur;      //新链表的头就是目前新链表的头
cur = old_head;        //接着处理
}

List = new_head;
}

//递归方式
void reverse_recursive(Node * old_head, Node * new_head){
if(old_head == NULL){
List = new_head;
return;
}

Node * tmp = old_head->next;        //将原来链表的头取出,并将第二个节点作为原来链表的头节点用于下一层递归
old_head->next = new_head; //将取出的头设为新链表的头
reverse_recursive(tmp, old_head);         //接着处理
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: