单向循环链表
相比于单向链表,单向循环链表仅仅是将单向链表的尾节点指向了头节点
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int data;
struct node *next;
}Node;
Node* InitList(){
Node* head = (Node*)malloc(sizeof(Node));
head->next = head;
return head;
}
int IsEmpty(Node *head) {
return head->next == head;
}
int InsertToListTail(Node *head, int data) {
Node *InsertNode = (Node*)malloc(sizeof(Node));
InsertNode->data = data;
if(!InsertNode) return 0;
Node *p = head;
while(p->next != head) p = p->next;
InsertNode->next = p->next;
p->next = InsertNode;
return 1;
}
int DelFromList(Node *head, int data) {
if(IsEmpty(head))return 0;
Node *pre = head;
Node *p = head->next;
while(p->data != data && p != head) {
pre = pre->next;
p = p->next;
}
if(p == head) return 0;
pre->next = p->next;
free(p);
return 1;
}
int UpdateList(Node *head, int index, int data) {
Node *p = head->next;
for(int i = 0; i < index && p!= head; i++ ) {
p = p->next;
}
if(p == head) return 0;
p->data = data;
return 1;
}
Node* FindNode(Node *head, int data) {
Node *p = head;
while(p->data != data && p != head) {
p = p->next;
}
if(p == head) return NULL;
else return p;
}
void PrintList(Node *head) {
if(head->next == head) printf("空链表");
Node *p = head->next;
while(p != head) {
printf("%d ",p->data);
p = p->next;
}
printf("\n");
}
双向链表
typedef struct node{
int data;
struct node *prev;
struct node *next;
}Node;
链表创建头结点[初始化]
Node* initList(){
Linklist head = (Linklist)malloc(sizeof(LNode));
head->next=NULL;
head->prev=NULL;
return head;
}
int isEmpty(Linklist head){
if(head->next==NULL && head->prev==NULL){
return 1;
}
return 0;
}
链表头插法创建 断开两个连接 特殊情况:
当只存在head结点时,head的next指针域为空。
已知Head结点和p结点,上面共四步:
Head->next=p;(1)
p->prev=Head;(2)
Head->next->prev=p;(3)
p->next=Head->next;(4)
3 4 1
void ListByInsertHead(Node* head ){
Node *p;
int x;
while(scanf("%d",&x)&&x!=-1){
p=(Linklist)malloc(sizeof(LNode)) ;
p->data=x;
if(head->next!=NULL){
head->next->prev=p;
}
p->next=head->next;
head->next=p;
p->prev=head;
}
return ;
}
链表尾插法创建 此时有四步改动
p->next=s;(1)
p=s;(2)
s->prev=p;(3)
s->next=p->next;(4)
3 2
void ListByInsertTail(Node* head ){
Node *p,*s;
p=head;
int x;
while(scanf("%d",&x)&&x!=-1){
s=(Node*)malloc(sizeof(Node)) ;
s->data=x;
s->next=p->next;
p->next=s;
s->prev=p;
p=s;
}
return ;
}
void ListByInsertTail(Node* head ){
Node *p,*s;
p=head;
int x;
while(scanf("%d",&x)&&x!=-1){
s=(Node*)malloc(sizeof(Node)) ;
s->data=x;
p->next=s;
s->prev=p;
p=s;
}
s->next=NULL;
return ;
}
指定结点前插入
在q结点前插入p结点
此处共有四处改动
p->prev=q->prev;(1)
q->prev->next=p;(2)
p->next=q;(3)
q->prev=p;(4)
void Insert(Node *p, Node *q){
p->prev=q->prev;
q->prev->next=p;
p->next=q;
q->prev=p;
}
链表删除 特殊:p为尾指针 上述有三处改动
p->prev->next=p->next;(1)
p->next=p->prev(2)
free(p)(3)
void delete_Node(Node *p){
p->prev->next=p->next;
if(p->next!=NULL){
p->next->prev=p->prev;
}
free(p);
}
循环双向链表的实现
小思考:自己实现循环双向链表
循环双向链表和双向链表的操作基本一致, 注意由于head指针的prev域和尾指针的next域不为空,因此部分操作需要增加对这两个指针的连接
双向循环链表完整代码:
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
typedef struct node{
int data;
struct node *prev;
struct node *next;
}LNode,*Linklist;
Linklist CreatList();
int isEmpty(Linklist head);
void ListByInsertHead(Linklist head );
void ListByInsertTail(Linklist head );
void Insert(LNode *p, LNode *q);
void delete_Node(LNode *p);
void delete_List(LNode *p);
void print_List(Linklist head);
int main(){
Linklist head = CreatList();
printf("%d\n",isEmpty(head));
ListByInsertTail(head);
print_List(head);
printf("\n");
LNode *t = (Linklist)malloc(sizeof(LNode));
t->data=10;
Insert(t,head->next);
print_List(head);
printf("\n");
delete_Node(t);
print_List(head);
delete_List(head);
return 0;
}
Linklist CreatList(){
Linklist head = (Linklist)malloc(sizeof(LNode));
head->next=head;
head->prev=head;
return head;
}
int isEmpty(Linklist head){
if(head->next==head && head->prev==head){
return 1;
}
return 0;
}
void ListByInsertHead(Linklist head ){
LNode *p;
int x;
while(scanf("%d",&x)&&x!=-1){
p=(Linklist)malloc(sizeof(LNode)) ;
p->data=x;
head->next->prev=p;
p->next=head->next;
head->next=p;
p->prev=head;
}
return ;
}
void ListByInsertTail(Linklist head ){
LNode *p,*s;
p=head;
int x;
while(scanf("%d",&x)&&x!=-1){
s=(Linklist)malloc(sizeof(LNode)) ;
s->data=x;
s->next=p->next;
p->next->prev=s;
p->next=s;
s->prev=p;
p=s;
}
return ;
}
void Insert(LNode *p, LNode *q){
p->prev=q->prev;
q->prev->next=p;
p->next=q;
q->prev=p;
}
void delete_Node(LNode *p){
p->prev->next=p->next;
p->next->prev=p->prev;
free(p);
}
void delete_List(LNode *p){
LNode *t,*temp;
t=p->next;
while(t!=p&&t!=p){
temp=t->next;
delete_Node(t);
t=temp;
print_List(p);
printf("\n");
}
free(p);
}
void print_List(Linklist head){
Linklist p;
p=head->next;
while(1){
printf("%d ",p->data);
if(p->next==head){
break;
}
p=p->next;
}
system("pause");
printf("\n");
while(1){
printf("%d ",p->data);
if(p->prev==head){
break;
}
p=p->prev;
}
}
|