链表基本操作及代码
2013-08-29 19:40
369 查看
这里介绍链表的基本操作及其C语言实现代码
一、单向链表
1、创建
一般传入链表长度,返回头节点
List *CreateList(int n)
{
List *head = NULL;//头节点
List *tail = NULL;//尾节点
List *p = NULL;//临时接入节点
printf("create a list with n length!\n");
while(n-- > 0)
{
p = (List *)malloc(sizeof(List));
if(p == NULL)
{
exit(-1);
}
printf("please input data of list\n");
scanf("%d", &p->data);
p->next = NULL;//插入一个节点,next=NULL,方便理解
if(head == NULL)
{
head = p;//头节点
tail = head;//
}
else
{
tail->next = p;//别被搞糊涂了,不就为了与上以节点连接么
tail = p;//本质就是让新节点变成尾节点,并与上以节点连接
}
}
return head;
}
2、释放节点
注意释放次序
void Free(List *head)
{
List *p = NULL;
while(head->next != NULL)
{
p = head->next;//记得保存下一个节点
free(head);
head = p;
}
free(head);
head = NULL;
}
3、链表遍历
void ListOut(List *head)
{
if(head == NULL)
{
printf("empity list !\n");
return ;
}
while(head->next != NULL)
{
printf("%d ", head->data);
head = head->next;
}
printf("%d\n", head->data);
}
4、插入节点
这里注意一点,如果要输出头节点,有两种方式:1、通过return 返回,2、传入头结点地址即&head
这里最容易出错!!还有注意节点指向的位置,尤其头节点!!
void Insert(List **head, int pos)
{
List *p = NULL;
List *q = NULL;
List *newl = NULL;
int val;
int i = 0;
if(pos < 0)
{
printf("your position is must >= 0!\n");
return;
}
printf("please input the data of new node!\n");
scanf("%d", &val);
newl = (List *)malloc(sizeof(List));
newl->data = val;
newl->next = NULL;
p = *head;
while(i != pos && NULL !=p->next)
{
q = p;
p = p->next;
i++;
}
if(i == pos)
{
if(i == 0)
{
q = *head;
*head = new1;
new1->next = q;
return;
}
else
{
q->next = newl;
newl->next = p;
return;
}
else if(i+1 == pos)
{
p->next = new1;
new1->next = NULL;
return ;
}
else
{
printf("your position is too big !\n ");
return ;
}
}
5、链表逆序
void reverse(List **head)
{
//注意若逆序输出的表头仍然用传入表头,必须对传入参数取地址&head
//如同int 一样,只能通过改变表头(指针)地址来改变其指向,不然List *head只是临时变量不会改变原参数
List *p = NULL;
List *temp = NULL;//临时节点
p = *head;
*head = NULL;//逆序第一个节点->next = NULL,这里head不再起左右,只是当作一个临时变量并最后保存新head而已。
while(p->next != NULL)
{
temp = p;
p = p->next;//先保存,不然后面就变了
temp->next = *head;
*head = temp;
}
p->next = *head;
*head = p;
}
二、双向链表
typedef struct List
{
int data;
struct List *prev;
struct List *next;
}List;
1、创建
List *CreateDlist(int n)
{
List *head = NULL;
List *p = NULL;
List *tail = NULL;
while(n--)
{
p = (List *)malloc(sizeof(List));
if(NULL == p)
{
printf("no memory for p!\n");
exit(-1);
}
printf("please input data of nodes\n");
scanf("%d", &p->data);
if(NULL == head)
{
tail = p;
head = tail;
tail->prev = head;
head->next = tail;
}
else
{
tail->next = p;
p->prev = tail;
p->next = p;
tail = p;
}
}
return head;
}
2、遍历
void Display(List *head)
{
List *p = head;
while(p->next != p)
{
printf("%d ", p->data);
p = p->next;
}
printf("%d\n", p->data);
}
3、插入
void Insert(List **head, int pos)
{
List *p = *head;
List *temp = NULL;
List *q = NULL;
int i = 0;
q = (List *)malloc(sizeof(List));
if(NULL == q)
{
printf("no memory for node!\n");
exit(-1);
}
printf("please input the data of new node!\n");
scanf("%d", &q->data);
while(p->next != p)
{
if(i == pos)
{
if(p == *head)//header
{
temp = *head;
*head = q;
(*head)->next = temp;
(*head)->prev = *head;
temp->prev = *head;
i++;
break;
}
else
{
temp = p->prev;
temp->next = q;
q->prev = temp;
q->next = p;
p->prev = q;
i++;//for the last node insert
break;
}
}
else
{
p = p->next;
i++;
}
}
if((i == pos) && ( p->next == p))//tail
{
temp = p->prev;
temp->next = q;
q->prev = temp;
q->next = p;
p->prev = q;
}
}
3、释放节点
void Free(List *head)
{
List *p = NULL;
while(head->next != head)
{
p = head->next;
free(head);
head = p;
}
free(head);
printf("free nodes sucessfully!\n");
}
4、逆序输出
void Reverse(List **head)
{
List *p = *head;
List *temp = NULL;
while(p->next != p)//这比单向列表简单多了
{
temp = p->next;
p->next = p->prev;
p->prev->prev = p;
p = temp;
}
p->next = p->prev;//tail
p->prev->prev = p;
p->prev = p;
*head = p;
}
int main()
{
int n;
List *head;
int pos;
printf("length of list!\n");
scanf("%d", &n);
head = CreateDlist(n);
Display(head);
/*
while(1)
{
printf("please input the position) of node you want to insert!\n");
scanf("%d", &pos);
Insert(&head, pos);
Display(head);
}
*/
Reverse(&head);
Display(head);
Free(head);
return 0;
}
一、单向链表
1、创建
一般传入链表长度,返回头节点
List *CreateList(int n)
{
List *head = NULL;//头节点
List *tail = NULL;//尾节点
List *p = NULL;//临时接入节点
printf("create a list with n length!\n");
while(n-- > 0)
{
p = (List *)malloc(sizeof(List));
if(p == NULL)
{
exit(-1);
}
printf("please input data of list\n");
scanf("%d", &p->data);
p->next = NULL;//插入一个节点,next=NULL,方便理解
if(head == NULL)
{
head = p;//头节点
tail = head;//
}
else
{
tail->next = p;//别被搞糊涂了,不就为了与上以节点连接么
tail = p;//本质就是让新节点变成尾节点,并与上以节点连接
}
}
return head;
}
2、释放节点
注意释放次序
void Free(List *head)
{
List *p = NULL;
while(head->next != NULL)
{
p = head->next;//记得保存下一个节点
free(head);
head = p;
}
free(head);
head = NULL;
}
3、链表遍历
void ListOut(List *head)
{
if(head == NULL)
{
printf("empity list !\n");
return ;
}
while(head->next != NULL)
{
printf("%d ", head->data);
head = head->next;
}
printf("%d\n", head->data);
}
4、插入节点
这里注意一点,如果要输出头节点,有两种方式:1、通过return 返回,2、传入头结点地址即&head
这里最容易出错!!还有注意节点指向的位置,尤其头节点!!
void Insert(List **head, int pos)
{
List *p = NULL;
List *q = NULL;
List *newl = NULL;
int val;
int i = 0;
if(pos < 0)
{
printf("your position is must >= 0!\n");
return;
}
printf("please input the data of new node!\n");
scanf("%d", &val);
newl = (List *)malloc(sizeof(List));
newl->data = val;
newl->next = NULL;
p = *head;
while(i != pos && NULL !=p->next)
{
q = p;
p = p->next;
i++;
}
if(i == pos)
{
if(i == 0)
{
q = *head;
*head = new1;
new1->next = q;
return;
}
else
{
q->next = newl;
newl->next = p;
return;
}
else if(i+1 == pos)
{
p->next = new1;
new1->next = NULL;
return ;
}
else
{
printf("your position is too big !\n ");
return ;
}
}
5、链表逆序
void reverse(List **head)
{
//注意若逆序输出的表头仍然用传入表头,必须对传入参数取地址&head
//如同int 一样,只能通过改变表头(指针)地址来改变其指向,不然List *head只是临时变量不会改变原参数
List *p = NULL;
List *temp = NULL;//临时节点
p = *head;
*head = NULL;//逆序第一个节点->next = NULL,这里head不再起左右,只是当作一个临时变量并最后保存新head而已。
while(p->next != NULL)
{
temp = p;
p = p->next;//先保存,不然后面就变了
temp->next = *head;
*head = temp;
}
p->next = *head;
*head = p;
}
二、双向链表
typedef struct List
{
int data;
struct List *prev;
struct List *next;
}List;
1、创建
List *CreateDlist(int n)
{
List *head = NULL;
List *p = NULL;
List *tail = NULL;
while(n--)
{
p = (List *)malloc(sizeof(List));
if(NULL == p)
{
printf("no memory for p!\n");
exit(-1);
}
printf("please input data of nodes\n");
scanf("%d", &p->data);
if(NULL == head)
{
tail = p;
head = tail;
tail->prev = head;
head->next = tail;
}
else
{
tail->next = p;
p->prev = tail;
p->next = p;
tail = p;
}
}
return head;
}
2、遍历
void Display(List *head)
{
List *p = head;
while(p->next != p)
{
printf("%d ", p->data);
p = p->next;
}
printf("%d\n", p->data);
}
3、插入
void Insert(List **head, int pos)
{
List *p = *head;
List *temp = NULL;
List *q = NULL;
int i = 0;
q = (List *)malloc(sizeof(List));
if(NULL == q)
{
printf("no memory for node!\n");
exit(-1);
}
printf("please input the data of new node!\n");
scanf("%d", &q->data);
while(p->next != p)
{
if(i == pos)
{
if(p == *head)//header
{
temp = *head;
*head = q;
(*head)->next = temp;
(*head)->prev = *head;
temp->prev = *head;
i++;
break;
}
else
{
temp = p->prev;
temp->next = q;
q->prev = temp;
q->next = p;
p->prev = q;
i++;//for the last node insert
break;
}
}
else
{
p = p->next;
i++;
}
}
if((i == pos) && ( p->next == p))//tail
{
temp = p->prev;
temp->next = q;
q->prev = temp;
q->next = p;
p->prev = q;
}
}
3、释放节点
void Free(List *head)
{
List *p = NULL;
while(head->next != head)
{
p = head->next;
free(head);
head = p;
}
free(head);
printf("free nodes sucessfully!\n");
}
4、逆序输出
void Reverse(List **head)
{
List *p = *head;
List *temp = NULL;
while(p->next != p)//这比单向列表简单多了
{
temp = p->next;
p->next = p->prev;
p->prev->prev = p;
p = temp;
}
p->next = p->prev;//tail
p->prev->prev = p;
p->prev = p;
*head = p;
}
int main()
{
int n;
List *head;
int pos;
printf("length of list!\n");
scanf("%d", &n);
head = CreateDlist(n);
Display(head);
/*
while(1)
{
printf("please input the position) of node you want to insert!\n");
scanf("%d", &pos);
Insert(&head, pos);
Display(head);
}
*/
Reverse(&head);
Display(head);
Free(head);
return 0;
}
相关文章推荐
- SqListFunc顺序链表的12个基本操作的C语言代码(数据结构)
- 链表解说和基本操作练习附代码
- 单链表基本操作代码
- 链表讲解和基本操作练习附代码
- c语言单链表的基本操作(代码)
- 单链表的基本操作,正序/逆序建表(尾插法/头插法)、计算单链表长度、输出单链表内容、插入、删除,给出完整代码
- 链表的基本操作与文件操作--期末大作业代码部分
- 带头节点的单链表的基本操作
- 单链表的基本操作
- 链表的基本操作
- 单链表的基本操作(C语言实现)
- 数据结构链表基本操作
- 链表基本操作
- 链表的基本操作C/c++
- 数据库基本操作小摘(代码由mysql-essential-5.1.50-win32测试通过)
- 链表的java实现以及基本的增加,删除,排序操作
- 单链表的基本操作
- 【代码】C++实现二叉树基本操作及测试用例
- 双向链表的基本操作
- 双向链表的基本操作