注释部分为双向链表 与 双向循环链表区别
此程序为完整双向循环链表
#include<stdlib.h>
#include"Linklist.h"
int Linkinit(Node **l)
{
*l = (Node *)malloc(sizeof(Node)*1);
if(NULL == *l)
{
return FAILURE;
}
/*(*l)->next = NULL; //双向链表
(*l)->front = NULL;*/
(*l)->next = *l; // 双向循环
(*l)->front = *l;
return SUCCESS;
}
int Linkinsert(Node *l, int n, ElemType e)
{
Node *p = l;
int k = 1;
if(NULL == l)
{
return FAILURE;
}
if(n > Linklength(l) + 1)
{
return FAILURE;
}
//while(k < n && p != NULL)
while(k < n ) //**
{
p = p->next;
k++;
}
// if(k < n || p == NULL)
if(k > n ) //**
{
return FAILURE;
}
Node *q = (Node *)malloc(sizeof(Node)*1);
if(NULL == q)
{
return FAILURE;
}
q->data = e;
q->front = p;
q->next = p->next;
p->next = q;
//if(q->next != NULL) //**
q->next->front = q;
return SUCCESS;
}
int Linktraverse(Node *l,void (*p)(ElemType))
{
if(NULL == l)
{
return FAILURE;
}
Node *q = l;
while(q->next != l ) //不等于本身 **
{
q = q->next;
p(q->data);
}
return SUCCESS;
}
/*int LinkReverse(Node *l)
{
if(NULL == l)
{
return FAILURE;
}
Node *p = l->next;
l->next = NULL;
while(p != NULL)
{
Node *q = p;
p = p->next;
q->next = l->next;
l->next = q;
}
return SUCCESS;
}*/
int Linklength(Node *l)
{
if(NULL == l)
{
return FAILURE;
}
int len = 0;
Node *p = l->next;
while(p != l) // **
{
len++;
p = p->next;
}
return len;
}
int Linkempty(Node *l)
{
//return (l->next == NULL) ? TRUE :FALSE; **
return (l->next == l && l->front == l) ? TRUE : FALSE;
}
int Getelem(Node *l, int p,ElemType *e) //p位置
{
if(NULL == l || p < 1)
{
return FAILURE;
}
//Node *q = l; **
Node *q = l->next; //双向循环链表,q指向第一个结点
int i;
//for(i = 0;i < p && q != NULL;i++) **
for(i = 1;i < p && q != l; i++)
{
q = q->next;
}
if(q == l)
//if(!q)
{
return FAILURE;
}
*e = q->data;
return SUCCESS;
}
int LocateElem(Node *l,ElemType e,int (*p)(ElemType, ElemType))
{
if(NULL == l)
{
return FAILURE;
}
Node *q = l->next;
int len = 1;
while(q != l) //双向循环链表
{
if(p(e, q->data) == TRUE)
{
return len;
}
q = q->next;
len++;
}
return FAILURE;
}
int LinkDelete(Node *l, int p, ElemType *e)
{
Node *q = l;
int k = 1;
if(NULL == l)
{
return FAILURE;
}
//while(k < p && q != NULL) **
while(k < p)
{
q = q->next;
k++;
}
//if(k > p || q == NULL) **
if(k > p)
{
return FAILURE;
}
Node *n = q->next;
*e = n->data;
q->next = n->next;
//if(n->next != NULL) **
n->next->front = q;
free(n);
return SUCCESS;
}
int Linkclear(Node *l)
{
if(NULL == l)
{
return FAILURE;
}
Node *p = l->next;
while(p != l) // **
{
l->next = p->next;
free(p);
p = l->next;
}
l->front = l; //**
return SUCCESS;
}
int LinkDestroy(Node **l)
{
if(NULL == l)
{
return FAILURE;
}
free(*l);
(*l) = NULL;
return SUCCESS;
}
#include<stdio.h>
#include"Linklist.h"
void print(ElemType e)
{
printf("%d ",e);
}
int equal(ElemType e1, ElemType e2)
{
return (e1 == e2) ? TRUE : FALSE;
}
int main()
{
srand(time(NULL));
int ret, i;
Node *first = NULL;
ret = Linkinit(&first);
if(ret == FAILURE)
{
printf("Init Failure!\n");
}
else
{
printf("Init Success!\n");
}
for(i = 0;i < 10;i++)
{
ret = Linkinsert(first,i + 1,rand() % 10);
if(ret == FAILURE)
{
printf("Insert Failure!\n");
}
else
{
printf("Insert Success!\n");
}
}
ret = Linktraverse(first, print);
if(ret == FAILURE)
{
printf("\nTraverse Failure!\n");
}
else
{
printf("\nTraverse Success!\n");
}
/*ret = LinkReverse(first);
if(ret == FAILURE)
{
printf("\nReverse Failure!\n");
}
else
{
printf("\nReverse Success!\n");
}*/
ret = Linktraverse(first, print);
if(ret == FAILURE)
{
printf("\nTraverse Failure!\n");
}
else
{
printf("\nTraverse Success!\n");
}
ret = Linklength(first);
if(ret == FAILURE)
{
printf("Get Length Failure!\n");
}
else
{
printf("Length %d\n",ret);
}
ret = Linkempty(first);
if(ret == TRUE)
{
printf("List is empty!\n");
}
else if(ret == FALSE)
{
printf("List is not empty!\n");
}
int p = 3;
ElemType e;
ret = Getelem(first, p, &e);
if(ret == FAILURE)
{
printf("Get element failure!n\n");
}
else
{
printf("The %dth element is %d\n", p, e);
}
e = 10;
ret = LocateElem(first, e, equal);
if(FAILURE == ret)
{
printf("%d not exist!\n", e);
}
else
{
printf("%d is %dth element!\n", e, ret);
}
p = 3;
ret = LinkDelete(first, p, &e);
if(ret == FAILURE)
{
printf("Delete Failure!\n");
}
else
{
printf("Delete %d Success!\n",e);
}
ret = Linktraverse(first, print);
if(ret == FAILURE)
{
printf("\nTraverse Failure!\n");
}
else
{
printf("\nTraverse Success!\n");
}
ret = LinkDestroy(&first);
if(ret == SUCCESS)
{
printf("Destroy Success!\n");
}
else
{
printf("Destroy Failure!\n");
}
for(i = 0;i < 10;i++)
{
ret = Linkinsert(first, i + 1,rand() % 20);
if(ret == FAILURE)
{
printf("Insert Failure!\n");
}
else
{
printf("Insert Success\n");
}
}
return 0;
}
#ifndef _LINKLIST_H
#define _LINKLIST_H
#define FAILURE 10000
#define SUCCESS 10001
#define FALSE 10002
#define TRUE 10003
typedef int ElemType;
struct node
{
ElemType data;
struct node *next;
struct node *front;
};
typedef struct node Node;
int Linkinit(Node **l);
int Linkinsert(Node *l,int n, ElemType e);
int Linktraverse(Node *l,void (*p)(ElemType));
int Linklength(Node *l);
int Getelem(Node *l, int p, ElemType *e);
int Linkempty(Node *l);
int LocateElem(Node *l, ElemType e, int (*p)(ElemType,ElemType));
int LinkDelete(Node *l, int p, ElemType *e);
int LinkReverse(Node *l);
int LinkDestroy(Node **l);
int Linkclear(Node *l);
#endif
顺序表与链表的比较
基于空间的比较
存储分配的方式 顺序表的存储空间是静态分配的 链表的存储空间是动态分配的
存储密度 = 结点数据本身所占的存储量/结点结构所占的存储总量
顺序表的存储密度 = 1 链表的存储密度 < 1
基于时间的比较
存取方式
顺序表可以随机存取,也可以顺序存取 链表是顺序存取的
插入/删除时移动元素个数 顺序表平均需要移动近一半元素 链表不需要移动元素,只需要修改指针 若插入/删除仅发生在表的两端,宜采用带尾指针的循环链表
#include"SequenceStack.h"
#include<stdio.h>
int main()
{
Stack *stack;
int ret;
ret = Stackinit(&stack); //stack是野指针,要修改stack的值(地址)
if(ret == SUCCESS)
{
printf("Init Success!\n");
}
else
{
printf("Failure!\n");
}
ret = StackEmpty(stack);
if(ret == TRUE)
{
printf("stack is empty\n");
}
else
{
printf("stack is not empty\n");
}
int i = 0;
for(i = 0;i < 12;i++)
{
ret = push(stack, i + 1);
if(ret == SUCCESS)
{
printf("push %d success\n",i + 1);
}
else if(ret == FAILURE)
{
printf("push %d failure\n",i + 1);
}
}
ret = GetTop(stack);
if(ret == FAILURE)
{
printf("Get Top failure\n");
}
else
{
printf("Top is %d\n ",ret);
}
for(i = 0;i < 5;i++)
{
ret = pop(stack);
if(ret == FAILURE)
{
printf("pop failure\n");
}
else
{
printf("pop success\n");
}
}
ret = GetTop(stack);
if(ret == FAILURE)
{
printf("Get Top failure\n");
}
else
{
printf("Top is %d\n",ret);
}
ret = StackClear(stack);
if(ret == FAILURE)
{
printf("Clear failure\n");
}
else
{
printf("Clear success\n");
}
ret = StackDestroy(&stack);
if(ret == FAILURE)
{
printf("Destroy failure\n");
}
else
{
printf("Destroy success\n");
}
for(i = 0;i < 12;i++)
{
ret = push(stack, i + 1);
if(ret == SUCCESS)
{
printf("push %d success\n",i + 1);
}
else if(ret == FAILURE)
{
printf("push %d failure\n",i + 1);
}
}
return 0;
}
#include<stdlib.h>
#include"SequenceStack.h"
int Stackinit(Stack **s)
{
(*s) = (Stack *)malloc(sizeof(Stack)*1); //分配一个结构体,用于保存栈的信息
if(NULL == *s)
{
return FAILURE;
}
(*s)->top = -1; //空栈 栈顶为-1
(*s)->data =(ElemType *)malloc(sizeof(ElemType)*SIZE); //为栈分配空间
if(NULL == (*s)->data)
{
return FAILURE;
}
return SUCCESS;
}
int StackEmpty(Stack *s)
{
return (s->top == -1) ? TRUE : FALSE;
}
int push(Stack *s, ElemType e)
{
if(NULL == s || s->top == 9) //入参判断
{
return FAILURE;
}
s->data[s->top + 1] = e; //进栈
s->top++;
return SUCCESS;
}
int GetTop(Stack *s)
{
if(s->top == -1)
{
return FAILURE;
}
return s->data[s->top];
}
int pop(Stack *s)
{
if(s->top == -1)
{
return FAILURE;
}
s->top--;
return SUCCESS;
}
int StackClear(Stack *s)
{
if(s->top == -1)
{
return FAILURE;
}
s->top = -1;
return SUCCESS;
}
int StackDestroy(Stack **s)
{
if(s == NULL || *s == NULL)
{
return FAILURE;
}
free((*s)->data);
free(*s);
*s = NULL; // 为了使其不成为野指针
return SUCCESS;
}
#ifndef _SEQUENCESTACK_H
#define _SEQUENCESTACK_H
#define SUCCESS 10000
#define FAILURE 10001
#define TRUE 10002
#define FALSE 10003
#define SIZE 10
typedef int ElemType;
typedef struct stack Stack;
struct stack
{
int top;
ElemType *data;
};
int Stackinit(Stack **s);
int StackEmpty(Stack *s);
int push(Stack *s, ElemType e);
int pop(Stack *s);
int GetTop(Stack *s);
int StackClear(Stack *s);
int StackDestroy(Stack **s);
#endif