一、数据结构线性表
1.顺序存储结构的插入
①用指针指向被操作的线性表,静态分配
int Insert(Sqlist *L,int i,ElemType e)
{ if(i<1||i>L->length+1) return ERROR; //i值不合法
if(L->length>=maxleng) return OVERFLOW; //溢出
for(j=L->length;j>=i-1;j–)
L->elem[j+1]=L->elem[j]; //从后往前,向后移动元素
L->elem[i-1]=e; //插入新元素
L->length++; //长度加1
return ok;
}
②用引用参数表示被操作的线性表
int Insert(Sqlist &L,int i,ElemType e)
{ if(i<1||i>L.length+1) return ERROR; //i值不合法
if(L.length>=maxleng) return OVERFLOW; //溢出
for(j=L.length;j>=i-1;j–)
L.elem[j+1]=L.elem[j]; //从后往前,向后移动元素
L.elem[i-1]=e; //插入新元素
L.length++; //长度加1
return ok;
}
③动态分配线性表空间,用引用参数表示被操作的线性表
int Insert(Sqlist &L,int i,ElemType e)
{int j;
if(i<1||i>L.length+1) return ERROR; //i值不合法
if(L.length>=L.listsize) //溢出扩充
ElemType *newbase;
newbase=(Elemtype *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
If(newbaseNULL) return OVERFLOW;
L.elem=newbase;
L.listsize+=LISTINCREMENT;
for(j=L.length-1;j>=i-1;j–)
L.elem[j+1]=L.elem[j];
L.length++;
return ok;
}
2.顺序存储结构的删除
int delete(Sqlist *L,int i)
{if(i<1||i>L->length)
{printf(“error”);
return error;}
else{for(j=1;j<=L->length-1;j++)
L->elem[j-1]=L->elem[j]; //从前往后,向前覆盖元素
L->length–;return ok;}
}
3.单链表的链式存储
①链表:线性表采用链式方式将结点链接起来的存储方式称为链表。
②单链表的结点结构:
数据域存储结点的值;指针域存储数据元素后继的位置。
③单链表基本运算
1)求单链表长度
int Listlength(Linklist L)
{Node *p;
P=->next;
j=0;
while(p!=NULL)
{p=p->next;
j++;
}return j;
}
2)建立单链表
建立空表:
InitList(Linklist *L)
{L=(Linklist)malloc(sizeof(Node));
L->next=NULL;
}
头插法建表:
{S=(Node *)malloc(sizeof(Node));
S->data=c;
L->next=L->next;
L->next=s;
}
3)单链表查找
按序号查找:
while((p->next!=NULL)&&(j<i))
{p=p->next;
j++;
}
if(ij) return p;
else return NULL;
按值查找:
Node *p;
p=L->next;
while(p!=NULL)
if(p->data!=key)
p=p->next;
else break;
return p;
4)单链表插入
while(pre!=NULL&&k<i-1)
{pre=pre->next;
K=k+1;
}
if(!pre)
{printf(“插入位置不合理!”)
}
s>data=e;
S->next=pre->next;pre->next=s;
5)单链表删除
while(p->next!=NULL&&k<i-1)
{
p=p->next;
K=k+1;
}
if(k!=i-1)
{printf(“删除结点不合理!”);
return;
}
r=p->next;
p->next=r->next;
e=r->data;
free®;
4.双向链表的实现
双链表的插入:
1)s->prior=p->prior 2) P->prior->next=s
3)s->next=p 4) P->prior=s
双链表的删除:
1)p->prior->next=p->next
2)P->next->prior=p->prior
3)free§
二、Linux双链表的插入、删除和遍历
static int __init doublelist_init(void) //初始化函数
{
struct numlist * listnode; //指向结构体的指针listnode
struct list_head *pos; //指向双链表指针域的指针pos
struct numlist *p; //指向结构体的指针p
int i;
printk("doublelist is starting:\n");
INIT_LIST_HEAD(&numhead.list);
//#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0) // 通过前驱和后继分别指向自己来达到初始化作用
for(i=0;i<N;i++){
listnode=(struct numlist *)kmalloc(sizeof(struct numlist),GFP_KERNEL);
listnode->num=i+1;
list_add_tail(&listnode->list,&numhead.list);
1)//static inline void list_add_tail(struct list_head *new,struct list_head *head)
{__list_add(new,head->prev,head);
}
2)//static inline void __list_add(struct list_head *new,struct list_head *prev,struct list_head *next)
{next->prev=new;
new->next=next;
new->prev=prev;
prev->next=new;
} (listnode为每次申请链表结点时作用的指针相当于new,numhead为头结点,listnode->list和numhead.list均指向其指针域。)
printk(“Node %d has added to the doublelist\n”,i+1);
}
i=1;
list_for_each(pos,&numhead.list){ //起遍历作用
p=list_entry(pos,struct numlist,list); //得到起始地址
printk("Node %d's data::%d\n",i,p->num);
i++;
}
//#define list_for_each(pos,head) 遍历链表
for(pos=(head)->next;pos!=(head);pos=pos->next))
return 0;
//#define list_entry(ptr,type,member)
((type*)((char )(ptr)-(unsigned long)(&((type)0)->member))) 绝对地址-偏移量
static void __exit doublelist_exit(void){
struct list_head *pos,*n;
struct numlist *p;
int i;
i=1;
list_for_each_safe(pos,n,&numhead.list){
list_del(pos);
p=list_entry(pos,struct numlist,list);
kfree(p);
printk("Node %d has removed from the doublelist",i++);
}
printk("doublelist is exiting\n");
}
三 malloc relloc和calloc的区别
Void *malloc(size_t,size) //从堆空间中申请指定的size个字节的内存大小,记得memset进行初始化。
Void calloc(size_t size,size_t length) //相当于malloc(sizelength),和malloc的区别是自动将申请到的空间值设置为0
Void *realloc(void *mem_address,size_t new_size) //用来重新指定空间大小,对原空间进行简单的扩展